CRITICAL: Change the default admin/admin credentials immediately after deployment.
Edit config/local.json:
{
"auth": {
"username": "your-secure-username",
"password": "your-very-strong-password-here"
},
"sessionSecret": "generate-a-random-32-char-string-here"
}Always use HTTPS in production. HTTP connections expose terminal sessions and credentials.
Use nginx or Apache as a reverse proxy with SSL:
server {
listen 443 ssl http2;
server_name yourdomain.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}# Install certbot
sudo dnf install certbot python3-certbot-nginx
# Get certificate
sudo certbot --nginx -d yourdomain.comOnly expose necessary ports:
# Allow only HTTP/HTTPS
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --permanent --remove-port=3000/tcp
sudo firewall-cmd --reloadRestrict access to known IPs by editing src/server.js:
const allowedIPs = ['1.2.3.4', '5.6.7.8'];
app.use((req, res, next) => {
const clientIP = req.ip || req.connection.remoteAddress;
if (!allowedIPs.includes(clientIP)) {
return res.status(403).send('Access denied');
}
next();
});The current implementation includes:
- β 30-minute session timeout
- β httpOnly cookies (prevents XSS)
- β Login rate limiting (5 attempts per 15 min)
- β Secure session IDs
Enhance further by setting secure cookies in production:
// In config/local.json
{
"session": {
"secure": true, // Only send over HTTPS
"sameSite": "strict"
}
}Keep dependencies updated to patch security vulnerabilities:
npm audit
npm audit fix
npm updateDO NOT run termi-host as root in production. Create a dedicated user:
sudo useradd -r -s /bin/false termihost
sudo chown -R termihost:termihost /path/to/termi-host
# Update systemd service to run as termihost user
sudo systemctl edit termi-host
# Add: User=termihostEnable logging for security auditing:
// Add to server.js
const fs = require('fs');
const accessLog = fs.createWriteStream('/var/log/termi-host/access.log', { flags: 'a' });
app.use((req, res, next) => {
const log = `${new Date().toISOString()} ${req.ip} ${req.method} ${req.url}\n`;
accessLog.write(log);
next();
});For public/demo environments, consider restricting dangerous commands:
const blockedCommands = ['rm -rf', 'mkfs', 'dd if=', ':(){:|:&};:'];
// In PTY data handler
pty.on('data', (data) => {
const hasBlockedCmd = blockedCommands.some(cmd => data.includes(cmd));
if (hasBlockedCmd) {
ws.send('\r\nβ οΈ Command blocked for security\r\n');
return;
}
ws.send(data);
});Before going to production:
- Changed default credentials
- Generated strong session secret (32+ chars)
- Enabled HTTPS/SSL
- Configured firewall
- Set up reverse proxy
- Enabled secure cookies (
secure: true) - Tested rate limiting
- Reviewed access logs
- Disabled authentication bypass features
- Documented admin procedures
- Set up monitoring/alerts
- Created backup admin account
| Threat | Risk | Mitigation |
|---|---|---|
| Brute force login | High | Rate limiting (implemented) |
| Session hijacking | High | httpOnly cookies, HTTPS, short timeout |
| Man-in-the-middle | Critical | HTTPS required in production |
| XSS attacks | Medium | CSP headers (implemented) |
| Command injection | Low | PTY sandboxing, user permissions |
| DoS attacks | Medium | Connection limits, rate limiting |
| Credential exposure | Critical | Never commit secrets, use .env files |
If you suspect a security breach:
- Immediately stop the termi-host service:
systemctl stop termi-host - Review logs:
journalctl -u termi-host -n 500 - Change all credentials
- Review PTY command history
- Check for unauthorized processes:
ps aux | grep -v grep - Update and patch:
npm audit fix