Skip to content

Commit 4a0eb76

Browse files
committed
feat: add support for http and style output #22
1 parent ebe4475 commit 4a0eb76

18 files changed

+278
-139
lines changed

cmd/install.go

+23-35
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,6 @@ var installCmd = &cobra.Command{
2222

2323
relayDomain, _ := pterm.DefaultInteractiveTextInput.Show("Relay domain name")
2424
pterm.Println()
25-
pterm.Println(pterm.Yellow("Leave email empty if you don't want to receive notifications from Let's Encrypt about your SSL cert."))
26-
pterm.Println()
27-
ssl_email, _ := pterm.DefaultInteractiveTextInput.Show("Email address")
28-
pterm.Println()
2925

3026
// Supported relay options
3127
options := []string{"Khatru Pyramid", "strfry", "Khatru29", "WoT Relay"}
@@ -62,22 +58,20 @@ var installCmd = &cobra.Command{
6258
khatru_pyramid.ConfigureNginxHttp(relayDomain)
6359

6460
// Step 4: Get SSL certificates
65-
var shouldContinue = network.GetCertificates(relayDomain, ssl_email)
66-
if !shouldContinue {
67-
return
61+
var httpsEnabled = network.GetCertificates(relayDomain)
62+
if httpsEnabled {
63+
// Step 5: Configure Nginx for HTTPS
64+
khatru_pyramid.ConfigureNginxHttps(relayDomain)
6865
}
6966

70-
// Step 5: Configure Nginx for HTTPS
71-
khatru_pyramid.ConfigureNginxHttps(relayDomain)
72-
7367
// Step 6: Download and install the relay binary
7468
khatru_pyramid.InstallRelayBinary()
7569

7670
// Step 7: Set up the relay service
7771
khatru_pyramid.SetupRelayService(relayDomain, pubkey)
7872

7973
// Step 8: Show success messages
80-
khatru_pyramid.SuccessMessages(relayDomain)
74+
khatru_pyramid.SuccessMessages(relayDomain, httpsEnabled)
8175
} else if selectedRelayOption == "strfry" {
8276
// Step 2: Configure the firewall
8377
network.ConfigureFirewall()
@@ -86,22 +80,20 @@ var installCmd = &cobra.Command{
8680
strfry.ConfigureNginxHttp(relayDomain)
8781

8882
// Step 4: Get SSL certificates
89-
var shouldContinue = network.GetCertificates(relayDomain, ssl_email)
90-
if !shouldContinue {
91-
return
83+
var httpsEnabled = network.GetCertificates(relayDomain)
84+
if httpsEnabled {
85+
// Step 5: Configure Nginx for HTTPS
86+
strfry.ConfigureNginxHttps(relayDomain)
9287
}
9388

94-
// Step 5: Configure Nginx for HTTPS
95-
strfry.ConfigureNginxHttps(relayDomain)
96-
9789
// Step 6: Download and install the relay binary
9890
strfry.InstallRelayBinary()
9991

10092
// Step 7: Set up the relay service
10193
strfry.SetupRelayService(relayDomain)
10294

10395
// Step 8: Show success messages
104-
strfry.SuccessMessages(relayDomain)
96+
strfry.SuccessMessages(relayDomain, httpsEnabled)
10597
} else if selectedRelayOption == "Khatru29" {
10698
// Step 2: Configure the firewall
10799
network.ConfigureFirewall()
@@ -110,22 +102,20 @@ var installCmd = &cobra.Command{
110102
khatru29.ConfigureNginxHttp(relayDomain)
111103

112104
// Step 4: Get SSL certificates
113-
var shouldContinue = network.GetCertificates(relayDomain, ssl_email)
114-
if !shouldContinue {
115-
return
105+
var httpsEnabled = network.GetCertificates(relayDomain)
106+
if httpsEnabled {
107+
// Step 5: Configure Nginx for HTTPS
108+
khatru29.ConfigureNginxHttps(relayDomain)
116109
}
117110

118-
// Step 5: Configure Nginx for HTTPS
119-
khatru29.ConfigureNginxHttps(relayDomain)
120-
121111
// Step 6: Download and install the relay binary
122112
khatru29.InstallRelayBinary()
123113

124114
// Step 7: Set up the relay service
125115
khatru29.SetupRelayService(relayDomain, privkey)
126116

127117
// Step 8: Show success messages
128-
khatru29.SuccessMessages(relayDomain)
118+
khatru29.SuccessMessages(relayDomain, httpsEnabled)
129119
} else if selectedRelayOption == "WoT Relay" {
130120
// Step 2: Configure the firewall
131121
network.ConfigureFirewall()
@@ -134,29 +124,27 @@ var installCmd = &cobra.Command{
134124
wot_relay.ConfigureNginxHttp(relayDomain)
135125

136126
// Step 4: Get SSL certificates
137-
var shouldContinue = network.GetCertificates(relayDomain, ssl_email)
138-
if !shouldContinue {
139-
return
127+
var httpsEnabled = network.GetCertificates(relayDomain)
128+
if httpsEnabled {
129+
// Step 5: Configure Nginx for HTTPS
130+
wot_relay.ConfigureNginxHttps(relayDomain)
140131
}
141132

142-
// Step 5: Configure Nginx for HTTPS
143-
wot_relay.ConfigureNginxHttps(relayDomain)
144-
145133
// Step 6: Download and install the relay binary
146134
wot_relay.InstallRelayBinary()
147135

148136
// Step 7: Set up the relay service
149-
wot_relay.SetupRelayService(relayDomain, pubkey)
137+
wot_relay.SetupRelayService(relayDomain, pubkey, httpsEnabled)
150138

151139
// Step 8: Show success messages
152-
wot_relay.SuccessMessages(relayDomain)
140+
wot_relay.SuccessMessages(relayDomain, httpsEnabled)
153141
}
154142

155143
pterm.Println()
156-
pterm.Println(pterm.Magenta("Join the NODE-TEC Discord to get support:"))
144+
pterm.Println(pterm.Cyan("Join the NODE-TEC Discord to get support:"))
157145
pterm.Println(pterm.Magenta("https://discord.gg/J9gRK5pbWb"))
158146
pterm.Println()
159-
pterm.Println(pterm.Magenta("We plan to use relay groups for support in the future..."))
147+
pterm.Println(pterm.Cyan("We plan to use relay groups for support in the future..."))
160148

161149
pterm.Println()
162150
pterm.Println(pterm.Magenta("You can re-run this installer with `rwz install`."))

pkg/network/certbot.go

+19-5
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,23 @@ import (
1010
)
1111

1212
// Function to get SSL certificates using Certbot
13-
func GetCertificates(domainName, email string) bool {
13+
func GetCertificates(domainName string) bool {
1414

15-
options := []string{"yes", "no"}
15+
var ThemeDefault = pterm.ThemeDefault
1616

17-
prompt := pterm.DefaultInteractiveContinue.WithOptions(options)
17+
var prompt = pterm.InteractiveContinuePrinter{
18+
DefaultValueIndex: 0,
19+
DefaultText: "Obtain SSL certificates?",
20+
TextStyle: &ThemeDefault.PrimaryStyle,
21+
Options: []string{"yes", "no"},
22+
OptionsStyle: &ThemeDefault.SuccessMessageStyle,
23+
SuffixStyle: &ThemeDefault.SecondaryStyle,
24+
Delimiter: ": ",
25+
}
1826

1927
pterm.Println()
2028
pterm.Println(pterm.Cyan("Do you want to obtain SSL certificates using Certbot?"))
21-
pterm.Println(pterm.Cyan("This step requires that you already have a configured domain name."))
29+
pterm.Println(pterm.Cyan("If you select 'yes', then this step requires that you already have a configured domain name."))
2230
pterm.Println(pterm.Cyan("You can always re-run this installer after you have configured your domain name."))
2331
pterm.Println()
2432

@@ -28,6 +36,11 @@ func GetCertificates(domainName, email string) bool {
2836
return false
2937
}
3038

39+
pterm.Println()
40+
pterm.Println(pterm.Yellow("Leave email empty if you don't want to receive notifications from Let's Encrypt about your SSL certificates."))
41+
42+
pterm.Println()
43+
email, _ := pterm.DefaultInteractiveTextInput.Show("Email address")
3144
pterm.Println()
3245

3346
spinner, _ := pterm.DefaultSpinner.Start("Checking SSL certificates...")
@@ -36,7 +49,8 @@ func GetCertificates(domainName, email string) bool {
3649

3750
// Check if certificates already exist
3851
if files.FileExists(fmt.Sprintf("%s/fullchain.pem", certificatePath)) &&
39-
files.FileExists(fmt.Sprintf("%s/privkey.pem", certificatePath)) {
52+
files.FileExists(fmt.Sprintf("%s/privkey.pem", certificatePath)) &&
53+
files.FileExists(fmt.Sprintf("%s/chain.pem", certificatePath)) {
4054
spinner.Info("SSL certificates already exist.")
4155
return true
4256
}

pkg/relays/khatru29/nginx_http.go

+35-9
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package khatru29
22

33
import (
44
"fmt"
5-
"github.com/nodetec/rwz/pkg/utils/directories"
65
"github.com/nodetec/rwz/pkg/utils/files"
76
"github.com/nodetec/rwz/pkg/utils/systemd"
87
"github.com/pterm/pterm"
@@ -16,8 +15,6 @@ func ConfigureNginxHttp(domainName string) {
1615

1716
var configContent string
1817

19-
directories.CreateDirectory(fmt.Sprintf("/var/www/%s/.well-known/acme-challenge/", domainName), 0755)
20-
2118
files.RemoveFile(configFilePath)
2219

2320
configContent = fmt.Sprintf(`map $http_upgrade $connection_upgrade {
@@ -35,21 +32,50 @@ server {
3532
listen [::]:80;
3633
server_name %s;
3734
38-
location /.well-known/acme-challenge/ {
39-
root /var/www/%s;
40-
allow all;
41-
}
42-
4335
location / {
36+
# First attempt to serve request as file, then
37+
# as directory, then fall back to displaying 404.
38+
try_files $uri $uri/ =404;
4439
proxy_pass http://websocket_khatru29;
4540
proxy_http_version 1.1;
4641
proxy_set_header Upgrade $http_upgrade;
4742
proxy_set_header Connection $connection_upgrade;
4843
proxy_set_header Host $host;
4944
proxy_set_header X-Forwarded-For $remote_addr;
5045
}
46+
47+
# Only return Nginx in server header
48+
server_tokens off;
49+
50+
#### Security Headers ####
51+
# Test configuration:
52+
# https://securityheaders.com/
53+
# https://observatory.mozilla.org/
54+
add_header X-Frame-Options DENY;
55+
56+
# Avoid MIME type sniffing
57+
add_header X-Content-Type-Options nosniff always;
58+
59+
add_header Referrer-Policy "no-referrer" always;
60+
61+
add_header X-XSS-Protection 0 always;
62+
63+
add_header Permissions-Policy "geolocation=(), midi=(), sync-xhr=(), microphone=(), camera=(), magnetometer=(), gyroscope=(), fullscreen=(self), payment=()" always;
64+
65+
#### Content-Security-Policy (CSP) ####
66+
add_header Content-Security-Policy "base-uri 'self'; object-src 'none'; frame-ancestors 'none';" always;
67+
}
68+
69+
server {
70+
listen 443 ssl http2;
71+
listen [::]:443 ssl http2;
72+
server_name %s;
73+
74+
location / {
75+
return 301 http://%s$request_uri;
76+
}
5177
}
52-
`, domainName, domainName, domainName)
78+
`, domainName, domainName, domainName, domainName)
5379

5480
files.WriteFile(configFilePath, configContent, 0644)
5581

pkg/relays/khatru29/nginx_https.go

+8-5
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package khatru29
22

33
import (
44
"fmt"
5+
"github.com/nodetec/rwz/pkg/utils/directories"
56
"github.com/nodetec/rwz/pkg/utils/files"
67
"github.com/nodetec/rwz/pkg/utils/systemd"
78
"github.com/pterm/pterm"
@@ -17,6 +18,8 @@ func ConfigureNginxHttps(domainName string) {
1718

1819
files.RemoveFile(configFilePath)
1920

21+
directories.CreateDirectory(fmt.Sprintf("/var/www/%s/.well-known/acme-challenge/", domainName), 0755)
22+
2023
configContent = fmt.Sprintf(`map $http_upgrade $connection_upgrade {
2124
default upgrade;
2225
'' close;
@@ -45,6 +48,9 @@ server {
4548
proxy_set_header X-Forwarded-For $remote_addr;
4649
}
4750
51+
# Only return Nginx in server header
52+
server_tokens off;
53+
4854
#### SSL Configuration ####
4955
# Test configuration:
5056
# https://www.ssllabs.com/ssltest/analyze.html
@@ -54,9 +60,6 @@ server {
5460
# Verify chain of trust of OCSP response using Root CA and Intermediate certs
5561
ssl_trusted_certificate /etc/letsencrypt/live/%s/chain.pem;
5662
57-
# Only return Nginx in server header
58-
server_tokens off;
59-
6063
# TODO
6164
# Add support to generate the file in the script
6265
#ssl_dhparam /etc/ssl/certs/dhparam.pem;
@@ -87,7 +90,7 @@ server {
8790
ssl_stapling on;
8891
ssl_stapling_verify on;
8992
90-
# Security headers
93+
#### Security Headers ####
9194
# Test configuration:
9295
# https://securityheaders.com/
9396
# https://observatory.mozilla.org/
@@ -104,7 +107,7 @@ server {
104107
105108
add_header Permissions-Policy "geolocation=(), midi=(), sync-xhr=(), microphone=(), camera=(), magnetometer=(), gyroscope=(), fullscreen=(self), payment=()" always;
106109
107-
# Content-Security-Policy (CSP)
110+
#### Content-Security-Policy (CSP) ####
108111
add_header Content-Security-Policy "base-uri 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests;" always;
109112
}
110113

pkg/relays/khatru29/success_messages.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ import (
44
"github.com/nodetec/rwz/pkg/utils/messages"
55
)
66

7-
func SuccessMessages(domain string) {
7+
func SuccessMessages(domain string, httpsEnabled bool) {
88
const dataDir = "/var/lib/khatru29"
99
const envFile = "/etc/systemd/system/khatru29.env"
1010
const serviceFile = "/etc/systemd/system/khatru29.service"
1111
const service = "khatru29"
1212
const relayName = "Khatru29"
1313
const githubLink = "https://github.com/fiatjaf/relay29/tree/master"
1414

15-
successMsgParams := messages.SuccessMsgParams{Domain: domain, DataDir: dataDir, EnvFile: envFile, ServiceFile: serviceFile, Service: service, RelayName: relayName, GitHubLink: githubLink}
15+
successMsgParams := messages.SuccessMsgParams{Domain: domain, HTTPSEnabled: httpsEnabled, DataDir: dataDir, EnvFile: envFile, ServiceFile: serviceFile, Service: service, RelayName: relayName, GitHubLink: githubLink}
1616
messages.SuccessMessages(&successMsgParams)
1717
}

0 commit comments

Comments
 (0)