Initial code commit
This commit is contained in:
313
internal/services/definitions.go
Normal file
313
internal/services/definitions.go
Normal file
@@ -0,0 +1,313 @@
|
||||
package services
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Service struct {
|
||||
Name string
|
||||
Port int
|
||||
Subdomain string
|
||||
Protocol string
|
||||
BackendPort int
|
||||
SNIRequired bool
|
||||
Config map[string]interface{}
|
||||
}
|
||||
|
||||
func GetDefaultServices(domain string) []Service {
|
||||
return []Service{
|
||||
{
|
||||
Name: "ssh",
|
||||
Port: 22,
|
||||
Subdomain: "ssh",
|
||||
Protocol: "ssh",
|
||||
BackendPort: 22,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{},
|
||||
},
|
||||
{
|
||||
Name: "https",
|
||||
Port: 443,
|
||||
Subdomain: "",
|
||||
Protocol: "tls",
|
||||
BackendPort: 8444,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"alpn_protocols": []string{"h2", "http/1.1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "smb",
|
||||
Port: 445,
|
||||
Subdomain: "smb",
|
||||
Protocol: "regex",
|
||||
BackendPort: 445,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\x00\\x00\\x00"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func GetAdditionalServices(domain string) []Service {
|
||||
return []Service{
|
||||
{
|
||||
Name: "ldap",
|
||||
Port: 389,
|
||||
Subdomain: "ldap",
|
||||
Protocol: "regex",
|
||||
BackendPort: 389,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\x30"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ldaps",
|
||||
Port: 636,
|
||||
Subdomain: "ldaps",
|
||||
Protocol: "tls",
|
||||
BackendPort: 636,
|
||||
SNIRequired: true,
|
||||
Config: map[string]interface{}{},
|
||||
},
|
||||
{
|
||||
Name: "rdp",
|
||||
Port: 3389,
|
||||
Subdomain: "rdp",
|
||||
Protocol: "regex",
|
||||
BackendPort: 3389,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\x03\\x00\\x00"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "mysql",
|
||||
Port: 3306,
|
||||
Subdomain: "mysql",
|
||||
Protocol: "regex",
|
||||
BackendPort: 3306,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^[\\x00-\\xff]{4}\\x0a"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "postgres",
|
||||
Port: 5432,
|
||||
Subdomain: "postgres",
|
||||
Protocol: "regex",
|
||||
BackendPort: 5432,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\x00\\x00\\x00\\x08"},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func GetStandardServices(domain string) []Service {
|
||||
return []Service{
|
||||
{
|
||||
Name: "ssh",
|
||||
Port: 22,
|
||||
Subdomain: "ssh",
|
||||
Protocol: "ssh",
|
||||
BackendPort: 22,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{},
|
||||
},
|
||||
{
|
||||
Name: "https",
|
||||
Port: 443,
|
||||
Subdomain: "",
|
||||
Protocol: "tls",
|
||||
BackendPort: 8444,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"alpn_protocols": []string{"h2", "http/1.1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ldap",
|
||||
Port: 389,
|
||||
Subdomain: "ldap",
|
||||
Protocol: "regex",
|
||||
BackendPort: 389,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\x30"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ldaps",
|
||||
Port: 636,
|
||||
Subdomain: "ldaps",
|
||||
Protocol: "tls",
|
||||
BackendPort: 636,
|
||||
SNIRequired: true,
|
||||
Config: map[string]interface{}{},
|
||||
},
|
||||
{
|
||||
Name: "smb",
|
||||
Port: 445,
|
||||
Subdomain: "smb",
|
||||
Protocol: "regex",
|
||||
BackendPort: 445,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\x00\\x00\\x00"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "rdp",
|
||||
Port: 3389,
|
||||
Subdomain: "rdp",
|
||||
Protocol: "regex",
|
||||
BackendPort: 3389,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\x03\\x00\\x00"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "mysql",
|
||||
Port: 3306,
|
||||
Subdomain: "mysql",
|
||||
Protocol: "regex",
|
||||
BackendPort: 3306,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^[\\x00-\\xff]{4}\\x0a"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "postgres",
|
||||
Port: 5432,
|
||||
Subdomain: "postgres",
|
||||
Protocol: "regex",
|
||||
BackendPort: 5432,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\x00\\x00\\x00\\x08"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "redis",
|
||||
Port: 6379,
|
||||
Subdomain: "redis",
|
||||
Protocol: "regex",
|
||||
BackendPort: 6379,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\*[0-9]"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "mongodb",
|
||||
Port: 27017,
|
||||
Subdomain: "mongo",
|
||||
Protocol: "regex",
|
||||
BackendPort: 27017,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^[\\x3d\\xdb]\\x00\\x00\\x00"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "vnc",
|
||||
Port: 5900,
|
||||
Subdomain: "vnc",
|
||||
Protocol: "regex",
|
||||
BackendPort: 5900,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^RFB"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ftp",
|
||||
Port: 21,
|
||||
Subdomain: "ftp",
|
||||
Protocol: "regex",
|
||||
BackendPort: 21,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^220"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "ftps",
|
||||
Port: 990,
|
||||
Subdomain: "ftps",
|
||||
Protocol: "tls",
|
||||
BackendPort: 990,
|
||||
SNIRequired: true,
|
||||
Config: map[string]interface{}{},
|
||||
},
|
||||
{
|
||||
Name: "smtp",
|
||||
Port: 25,
|
||||
Subdomain: "smtp",
|
||||
Protocol: "regex",
|
||||
BackendPort: 25,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^220"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "smtps",
|
||||
Port: 465,
|
||||
Subdomain: "smtps",
|
||||
Protocol: "tls",
|
||||
BackendPort: 465,
|
||||
SNIRequired: true,
|
||||
Config: map[string]interface{}{},
|
||||
},
|
||||
{
|
||||
Name: "imap",
|
||||
Port: 143,
|
||||
Subdomain: "imap",
|
||||
Protocol: "regex",
|
||||
BackendPort: 143,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\* OK"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "imaps",
|
||||
Port: 993,
|
||||
Subdomain: "imaps",
|
||||
Protocol: "tls",
|
||||
BackendPort: 993,
|
||||
SNIRequired: true,
|
||||
Config: map[string]interface{}{},
|
||||
},
|
||||
{
|
||||
Name: "pop3",
|
||||
Port: 110,
|
||||
Subdomain: "pop3",
|
||||
Protocol: "regex",
|
||||
BackendPort: 110,
|
||||
SNIRequired: false,
|
||||
Config: map[string]interface{}{
|
||||
"regex_patterns": []string{"^\\+OK"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "pop3s",
|
||||
Port: 995,
|
||||
Subdomain: "pop3s",
|
||||
Protocol: "tls",
|
||||
BackendPort: 995,
|
||||
SNIRequired: true,
|
||||
Config: map[string]interface{}{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) GetFQDN(domain string) string {
|
||||
return fmt.Sprintf("%s.%s", s.Subdomain, domain)
|
||||
}
|
||||
196
internal/services/installer.go
Normal file
196
internal/services/installer.go
Normal file
@@ -0,0 +1,196 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type ServiceInstaller struct {
|
||||
Service Service
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) GenerateInstallScript() string {
|
||||
var script strings.Builder
|
||||
|
||||
script.WriteString("#!/bin/bash\n")
|
||||
script.WriteString("set -e\n\n")
|
||||
|
||||
switch si.Service.Name {
|
||||
case "ssh":
|
||||
script.WriteString(si.installSSH())
|
||||
case "https":
|
||||
script.WriteString(si.installNginx())
|
||||
case "smb":
|
||||
script.WriteString(si.installSamba())
|
||||
case "ldap", "ldaps":
|
||||
script.WriteString(si.installLDAP())
|
||||
case "mysql":
|
||||
script.WriteString(si.installMySQL())
|
||||
case "postgres":
|
||||
script.WriteString(si.installPostgreSQL())
|
||||
case "redis":
|
||||
script.WriteString(si.installRedis())
|
||||
case "mongodb":
|
||||
script.WriteString(si.installMongoDB())
|
||||
default:
|
||||
script.WriteString(si.installGeneric())
|
||||
}
|
||||
|
||||
return script.String()
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) installSSH() string {
|
||||
return `# Configure SSH to listen on localhost only
|
||||
sed -i 's/#ListenAddress 0.0.0.0/ListenAddress 127.0.0.1/' /etc/ssh/sshd_config
|
||||
sed -i 's/ListenAddress 0.0.0.0/ListenAddress 127.0.0.1/' /etc/ssh/sshd_config
|
||||
systemctl restart sshd
|
||||
`
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) installNginx() string {
|
||||
return `# Configure Nginx to listen on localhost:8444 for HTTPS
|
||||
# Create demo page directory
|
||||
mkdir -p /var/www/demo
|
||||
cat > /var/www/demo/index.html <<'HTML'
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Demo App Page</title>
|
||||
<meta charset="utf-8">
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||
color: white;
|
||||
}
|
||||
.container {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-radius: 10px;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-size: 3rem;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Demo app page</h1>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
HTML
|
||||
|
||||
# Configure Nginx for root domain and subdomains
|
||||
cat > /etc/nginx/sites-available/sslh-proxy <<'EOF'
|
||||
# Default server for root domain (HTTPS on port 443 via SSLH)
|
||||
server {
|
||||
listen 127.0.0.1:8444 ssl http2;
|
||||
server_name _;
|
||||
|
||||
ssl_certificate /etc/ssl/certs/ssl-cert-snakeoil.pem;
|
||||
ssl_certificate_key /etc/ssl/private/ssl-cert-snakeoil.key;
|
||||
ssl_protocols TLSv1.2 TLSv1.3;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
|
||||
root /var/www/demo;
|
||||
index index.html;
|
||||
|
||||
location / {
|
||||
try_files $uri $uri/ =404;
|
||||
}
|
||||
}
|
||||
EOF
|
||||
ln -sf /etc/nginx/sites-available/sslh-proxy /etc/nginx/sites-enabled/
|
||||
rm -f /etc/nginx/sites-enabled/default
|
||||
nginx -t && systemctl restart nginx
|
||||
`
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) installSamba() string {
|
||||
return `# Configure Samba to listen on localhost only
|
||||
sed -i 's/; interfaces = 127.0.0.0\\/8/ interfaces = 127.0.0.1/' /etc/samba/smb.conf
|
||||
sed -i 's/; bind interfaces only = yes/ bind interfaces only = yes/' /etc/samba/smb.conf
|
||||
systemctl restart smbd
|
||||
`
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) installLDAP() string {
|
||||
return `# Install and configure OpenLDAP
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y slapd ldap-utils
|
||||
# Configure OpenLDAP to listen on localhost only
|
||||
sed -i 's|^SLAPD_SERVICES=.*|SLAPD_SERVICES="ldap://127.0.0.1:389/ ldaps://127.0.0.1:636/"|' /etc/default/slapd || true
|
||||
systemctl enable slapd
|
||||
systemctl restart slapd
|
||||
`
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) installMySQL() string {
|
||||
return `# Install MySQL/MariaDB and configure to listen on localhost
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y mysql-server || DEBIAN_FRONTEND=noninteractive apt-get install -y mariadb-server
|
||||
if [ -f /etc/mysql/mysql.conf.d/mysqld.cnf ]; then
|
||||
sed -i 's/bind-address.*/bind-address = 127.0.0.1/' /etc/mysql/mysql.conf.d/mysqld.cnf
|
||||
elif [ -f /etc/mysql/mariadb.conf.d/50-server.cnf ]; then
|
||||
sed -i 's/bind-address.*/bind-address = 127.0.0.1/' /etc/mysql/mariadb.conf.d/50-server.cnf
|
||||
fi
|
||||
systemctl restart mysql || systemctl restart mariadb
|
||||
`
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) installPostgreSQL() string {
|
||||
return `# Install PostgreSQL and configure to listen on localhost
|
||||
apt-get install -y postgresql postgresql-contrib
|
||||
for conf in /etc/postgresql/*/main/postgresql.conf; do
|
||||
if [ -f "$conf" ]; then
|
||||
sed -i "s/#listen_addresses = 'localhost'/listen_addresses = 'localhost'/" "$conf" || \
|
||||
sed -i "s/listen_addresses = '.*'/listen_addresses = 'localhost'/" "$conf" || \
|
||||
echo "listen_addresses = 'localhost'" >> "$conf"
|
||||
fi
|
||||
done
|
||||
systemctl restart postgresql
|
||||
`
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) installRedis() string {
|
||||
return `# Install Redis and configure to listen on localhost
|
||||
apt-get install -y redis-server
|
||||
sed -i 's/bind 127.0.0.1 ::1/bind 127.0.0.1/' /etc/redis/redis.conf
|
||||
systemctl restart redis-server
|
||||
`
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) installMongoDB() string {
|
||||
return `# Install MongoDB and configure to listen on localhost
|
||||
# Detect Ubuntu version for correct repository
|
||||
. /etc/os-release
|
||||
UBUNTU_VERSION=${VERSION_ID:-22.04}
|
||||
UBUNTU_CODENAME=${UBUNTU_CODENAME:-jammy}
|
||||
|
||||
# Add MongoDB GPG key using modern method
|
||||
mkdir -p /etc/apt/keyrings
|
||||
curl -fsSL https://www.mongodb.org/static/pgp/server-6.0.asc | gpg --dearmor -o /etc/apt/keyrings/mongodb-server-6.0.gpg
|
||||
chmod 644 /etc/apt/keyrings/mongodb-server-6.0.gpg
|
||||
|
||||
# Add MongoDB repository
|
||||
echo "deb [ arch=amd64,arm64 signed-by=/etc/apt/keyrings/mongodb-server-6.0.gpg ] https://repo.mongodb.org/apt/ubuntu ${UBUNTU_CODENAME}/mongodb-org/6.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-6.0.list
|
||||
apt-get update
|
||||
apt-get install -y mongodb-org
|
||||
sed -i 's/bindIp: .*/bindIp: 127.0.0.1/' /etc/mongod.conf
|
||||
systemctl enable mongod
|
||||
systemctl restart mongod
|
||||
`
|
||||
}
|
||||
|
||||
func (si *ServiceInstaller) installGeneric() string {
|
||||
return fmt.Sprintf(`# Generic service installation for %s
|
||||
echo "Service %s would be installed here"
|
||||
`, si.Service.Name, si.Service.Name)
|
||||
}
|
||||
Reference in New Issue
Block a user