Come può Discourse aggirare UFW? Avevo abilitato solo la porta 22, quindi tutte le altre porte dovrebbero essere chiuse. Ma un forum ha funzionato comunque. Come è possibile?
DigitalOcean droplet, ma ciò non dovrebbe significare nulla. E nessuna installazione one-click, ma il modo ufficiale.
Questa non è una pura domanda di supporto, ma qui non abbiamo una categoria chiamata Domande stupide e basilari dei principianti
Hai provato ad aprire il forum in una finestra di navigazione in incognito o in un browser diverso? È facile essere ingannati dalla versione memorizzata nella cache che viene visualizzata. Mi è successo e un altro sviluppatore mi ha detto che il sito di staging sembrava buono quando in realtà non era affatto in esecuzione.
Solo 22/tcp (OpenSSH) ALLOW IN Anywhere come dovrebbe essere. Queste sono le due cose che faccio sempre: consentire OpenSSH e abilitare UFW.
Apro le porte solo se necessario, ad esempio quando installerò Nginx. Ma poiché quel VPS era solo per Discourse non ho fatto altro: ho dimenticato completamente UFW.
Non può essere il caso. Quel forum era attivo da settimane.
Mi sono svegliato a questa situazione quando ho collegato Nginx/Varnish a quel VPS e avevo bisogno di un’altra porta aperta — e mi sono reso conto che solo la porta 22 era aperta.
Modifica:
Come potevo inviare email? Anche la porta 587 non era aperta
Non mi è chiaro se stai dicendo che l’impostazione predefinita è negata o meno. Il motivo per cui chiedo specificamente della riga “Default” è perché è possibile avere sia un’impostazione predefinita di consentire sia impostare una porta specifica da consentire, sebbene quest’ultima non cambi nulla in quella disposizione.
Se qualcun altro ha configurato Discourse, è possibile che quella persona abbia modificato l’impostazione predefinita su consentire invece di consentire le porte HTTP/HTTPS?
Presumo che si tratti di SMTP da qualche altra parte, il tuo server Discourse che si connette a quel server SMTP utilizzando la porta 587. Le connessioni in uscita sono consentite su tutte le porte per impostazione predefinita, quindi UFW non ostacolerà l’invio di email a meno che tu non modifichi esplicitamente la policy in uscita.
[quote=“Simon Manning, post:7, topic:231873, username:Simon_Manning”]è possibile che quella persona abbia cambiato il default in allow invece di consentire le porte HTTP/HTTPS?
[/quote]
No. Ma allow (outgoing) consente qualcosa in uscita? Se sì, allora siamo tornati a “non abbiamo qui una categoria chiamata Domande stupide e basilari dei principianti” e ho imparato cose nuove.
Modifica:
Sono ancora perso, ma come funziona deny (incoming)?
La risposta breve è che Discourse non può aggirare le regole del tuo firewall e il posto dove fare domande stupide su cose del sistema operativo è da qualche parte come Stack Exchange. (Per favore, non pensare che io sia scortese. È lì che si trovano quelle risposte. Dopo aver usato Linux fin dalle primissime versioni, vado ancora in posti come quello per tutte le mie domande stupide. Ne ho ancora!)
Conosco il posto C’è un rapporto segnale/rumore troppo alto. Beh, quella è stata una caratterizzazione ingiusta, ma intendevo dire che è davvero difficile trovare cose rilevanti da lì. È così massiccio.
Questa è in realtà un’ottima domanda e sono sorpreso che nessun altro l’abbia ancora posta. La risposta è complicata, ma finora le risposte su questo argomento sono state purtroppo sbrigative senza rispondere alla domanda.
Non è che Discourse stia aggirando ufw, ma docker aggira ufw aggiungendo regole che fanno funzionare le porte esposte dei container docker nonostante la presenza di ufw.
Cosa sta succedendo?
I pacchetti in arrivo destinati a un container colpiscono la tabella FORWARD, non la tabella INPUT come ci si potrebbe aspettare.
Installazione pre-docker
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 ufw-before-logging-forward all -- any any anywhere anywhere
0 0 ufw-before-forward all -- any any anywhere anywhere
0 0 ufw-after-forward all -- any any anywhere anywhere
0 0 ufw-after-logging-forward all -- any any anywhere anywhere
0 0 ufw-reject-forward all -- any any anywhere anywhere
0 0 ufw-track-forward all -- any any anywhere anywhere
Installazione post-docker
Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
8 416 DOCKER-USER all -- any any anywhere anywhere
8 416 DOCKER-ISOLATION-STAGE-1 all -- any any anywhere anywhere
0 0 ACCEPT all -- any docker0 anywhere anywhere ctstate RELATED,ESTABLISHED
4 256 DOCKER all -- any docker0 anywhere anywhere
4 160 ACCEPT all -- docker0 !docker0 anywhere anywhere
0 0 ACCEPT all -- docker0 docker0 anywhere anywhere
0 0 ufw-before-logging-forward all -- any any anywhere anywhere
0 0 ufw-before-forward all -- any any anywhere anywhere
0 0 ufw-after-forward all -- any any anywhere anywhere
0 0 ufw-after-logging-forward all -- any any anywhere anywhere
0 0 ufw-reject-forward all -- any any anywhere anywhere
0 0 ufw-track-forward all -- any any anywhere anywhere
Il motivo per cui i pacchetti raggiungono la tabella forward è dovuto alle regole che docker aggiunge alla tabella nat:
Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
210 12734 DOCKER all -- any any anywhere anywhere ADDRTYPE match dst-type LOCAL
Chain DOCKER (2 references)
pkts bytes target prot opt in out source destination
0 0 RETURN all -- docker0 any anywhere anywhere
0 0 DNAT tcp -- !docker0 any anywhere anywhere tcp dpt:https to:172.17.0.2:443
107 6848 DNAT tcp -- !docker0 any anywhere anywhere tcp dpt:http to:172.17.0.2:80
nat/PREROUTING viene elaborato prima che venga presa la decisione se inviare i pacchetti tramite INPUT o FORWARD.
In definitiva, il problema è che ci sono due servizi sul sistema che modificano le regole del firewall. ufw non è a conoscenza di nulla di tutto ciò, quindi può solo segnalare ciò che ha configurato.
Una soluzione
A questo problema è riconfigurare il firewall per far passare anche il traffico destinato a docker attraverso le chain di ufw:
Utilizzo la seguente leggera adattamento del loro lavoro, messo in atto prima di abilitare ufw:
# rubato da https://github.com/chaifeng/ufw-docker - sembra sensato
# aggiungere il forward a ufw-user-input consente le connessioni a
# porte inoltrate che abbiamo esplicitamente aperto
cat <<EOUFW >> /etc/ufw/after.rules
# BEGIN UFW AND DOCKER
*filter
:ufw-user-forward - [0:0]
:ufw-user-input - [0:0]
:DOCKER-USER - [0:0]
-A DOCKER-USER -j RETURN -s 10.0.0.0/8
-A DOCKER-USER -j RETURN -s 172.16.0.0/12
-A DOCKER-USER -j RETURN -s 192.168.0.0/16
-A DOCKER-USER -p udp -m udp --sport 53 --dport 1024:65535 -j RETURN
-A DOCKER-USER -j ufw-user-forward
-A DOCKER-USER -j ufw-user-input
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -d 192.168.0.0/16
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 10.0.0.0/8
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 172.16.0.0/12
-A DOCKER-USER -j DROP -p udp -m udp --dport 0:32767 -d 192.168.0.0/16
-A DOCKER-USER -j RETURN
COMMIT
# END UFW AND DOCKER
EOUFW
Questo argomento è risolto, ma ha rivelato un piccolo problema nella mia configurazione. Lo spiegherò se qualcuno cercherà qualcosa di simile in futuro.
Avevo un VPS dove Nginx si occupava di SSL e di altre cose di tutti i miei siti (molti errori, l’inglese è una lingua molto strana ). Nginx invia richieste a Varnish. È un reverse proxy inutile per Discourse, ma esegue alcuni filtri. Varnish invia richieste a un altro VPS dove risiede Discourse usando la porta 83. Entrambi i VPS ascoltano la stessa porta e è consentito solo a entrambi gli IP. Ero totalmente felice, fino ad ora.
Ho provato cosa succede quando ho usato la porta 443 curl -I https://forum.example.tld:443. Ha funzionato bene, perché ho ancora un certificato SSL valido sul lato di Discourse (ho fatto questa modifica alcune settimane fa).
La risposta di @supermathie spiega perché succede e come risolverlo. Certo, non ci sono problemi di sicurezza a causa di ciò, per quanto ne so, ma è davvero fastidioso
Immagino che non venga chiesto perché non capita spesso che qualcuno installi discourse e voglia che non funzioni, quindi quando docker lo fa funzionare quando hai configurato il firewall in modo che non dovrebbe, la maggior parte delle persone non si lamenta.
È un problema molto interessante, ma sembra un po’ esoterico, e non è un problema di Discourse, ma una stranezza di docker. La domanda si riduce a “come posso configurare il mio firewall per impedire il funzionamento di discourse?” Cercherò di ricordarmi quella roba del prerouting.
Se avessi saputo la risposta non sarei stato sprezzante! grazie per aver salvato la situazione in questo caso!
Non stavo certo cercando di essere sprezzante, ma piuttosto di risolvere i problemi… anche se evidentemente partivo da una posizione di ignoranza su ciò che Docker stava facendo. Tutte informazioni molto utili, grazie per aver risposto!
Se l’OP o qualcun altro può cambiarlo, potrebbe valere la pena cambiare la soluzione contrassegnata.
Anche se è più una cosa di Docker, posso vedere alcuni ipotetici scenari di Discourse che derivano da questo. Ad esempio, potrei avere un server d’ufficio raggiungibile dal mondo esterno, ma voglio configurare UFW per limitare l’accesso a Discourse solo dall’interno dell’ufficio. Le aggiunte di Docker impedirebbero tale configurazione.
Anche se in quello scenario particolare lo configurerei su un firewall hardware/hypervisor piuttosto che su UFW sull’host.
In realtà, l’ho capito dopo un po’ e ho scritto questo script bash per farlo per le installazioni di Discourse.
Ripristina il tuo firewall, installa ufw-docker-util (che modifica le regole after.rules), quindi aggiunge le porte 443 e 80 alla tua whitelist. Fatto.
Consente anche la porta 22 da qualsiasi IP per assicurarsi di non rimanere bloccato fuori. Dopo che tutto funziona, proteggi nuovamente la porta 22.
EDIT: lo script funziona ma la ricostruzione di Discourse dopo averlo utilizzato fallirà: fatal: unable to access 'https://github.com/discourse/discourse.git/': Could not resolve host: github.com - quindi NON usare lo script a meno che tu non sappia come risolvere questo problema.
L’ultima volta che ho fatto uno script bash ho cambiato il proprietario di tutte le directory in www-data:www-data — quindi per me un pezzo di lavoro come questo mi rende la vita un po’ più facile
Ma in generale — vorrei vedere docker seguire completamente UFW/iptables. Solo perché sto usando il blocco GeoIP tramite ipables (sì, lo so — UFW è solo un’interfaccia minimalista per iptables).
Certo, non siamo più su Discourse, ma qui possiamo vedere perché programmatori e utenti finali non si capiscono sempre così bene: i programmatori vedono il mondo come blocchi logici e costruzioni if/then/else, ma gli utenti finali lo vedono come contesto completo. Significato — perché uso Discourse, anche se funziona all’interno di docker, dal mio punto di vista è Discourse che non segue le mie regole
Questo dovrebbe andare in Praise ma ho cambiato l’url del forum qualche settimana fa. E ho fatto sì che tutti gli script kiddie del mondo e i bot SEO inutili visitassero. Ho ottenuto su un VPS da 2 GB/1 vcpu di DigitalOcean 3000 user agent diversi all’ora e Discourse semplicemente non se ne è curato. Qualsiasi installazione di WordPress sarebbe lenta/giù dopo quel tipo di corsa ddos’ish.
Quindi, non ho bisogno di forzare discourse (beh, docker) a seguire i ban di Fail2ban e le mie regole — ma odio così profondamente quei bot.