[Tutorial] Nginx als Reverse Proxy

(Edit 09.09.2011 – Nginx updated auf 1.0.6 / wget updated)
(Edit 31.12.2011 – Nginx updated auf 1.0.11 / wget updated)
(Edit 19.02.2012 – Nginx updated auf 1.0.12 / wget updated)
(Edit 20.05.2012 – Nginx updated auf 1.2.0 / wget updated)
(Edit 22.07.2012 – Nginx updated auf 1.2.2 / wget updated)

Nehmen wir an man betreibt ein… nicht ganz legales Projekt – Wie wohl alle wissen sind Offshore Server nicht gerade billig.
Im Vergleich:

Intel Xeon Nehalem 5503 (x2) 2.0Ghz
6Gb Ram
2 x 1Tb HDD
1000Mbit
1Tb Traffic
4 IPs
Panama
600 USD / 437 EUR – Kein Setup

Intel Xeon Nehalem 5504 (x2) 2.0Ghz
24Gb Ram
2 x 1,5Tb HDD
1000Mbit
15Tb Traffic
4 IPs
Frankreich
150 EUR – 50 EUR Setup

Wie man sieht, EU Server sind wirklich extrem billiger.

Nun, Wie kann man sich das zu nutze machen?

Einfach!

Man mietet einen billigen Server, irgendwo – in diesem beispiel bei OVH in Frankreich.
Dazu einen billigen VPS Server Offshore:

1 CPU Core (2.0Ghz)
1Gb Ram
100Gb HDD
200Gb Traffic
5 IPs
Panama
75 USD / 51 EUR – Kein Setup

Macht Total: 150+51 = 201 EUR inkl. Steuern (19%) – 286 EUR billiger als Komplett in Panama, mit mehr Ram und HDD.

Den OVH Server riegelt man nun komplett ab:
* SSH Port Ändern + Access nur via Keyfiles [+ Port Knocking, Optional]
* Webserver nur für die IP des VPS öffnen [+ Anderer Port, Optional]
* Datenbank Server nur für Lokalen Zugriff confen

Dann eben normal Forum oder andere Software Installieren.

Am VPS nun Nginx Compilen (Die Versionen in den Debian/Ubuntu Repos sind zum teil sehr veraltet):
(Ausgegangen wird von Debian/Ubuntu, und Root login)

apt-get update && apt-get upgrade
apt-get install nano libpcre* openssl libssl-dev gcc make build-essential
#Sollte alle benötigten Packages automatisch Installieren
wget http://nginx.org/download/nginx-1.2.2.tar.gz && tar -xvzf nginx-1.2.2.tar.gz && rm nginx-1.2.2.tar.gz
cd nginx-1.2.2/
./configure --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --pid-path=/var/run/nginx.pid --lock-path=/var/lock/nginx.lock --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/body --http-proxy-temp-path=/var/lib/nginx/proxy --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --with-debug --with-http_stub_status_module --with-http_flv_module --with-http_ssl_module --with-http_dav_module --with-http_gzip_static_module --with-http_realip_module --with-mail --with-mail_ssl_module --with-ipv6
#Es können einige Argumente entfernt werden, wie --with-mail
make -j$(cat /proc/cpuinfo | egrep -i '(processor*)' | wc -l) && make install && cp /usr/local/nginx/sbin/nginx /usr/sbin && cd /etc/init.d/ && wget --no-check-certificate rdns.im/ul/nginx && chmod +x /etc/init.d/nginx && mkdir /var/lib/nginx/ && cd /etc/nginx
rm *.default && rm nginx.conf && wget --no-check-certificate rdns.im/ul/nginx.conf && mkdir sites-enabled
nano sites-enabled/site

Ins Nano Fenster Pasten (vorher anpassen):

    server {
        listen       80;
        server_name  DOMAIN.COM;
        access_log  /var/log/nginx/access.log  main;
        error_log  /var/log/nginx/error.log;
        # Main location
        location / {
            proxy_pass         http://OVH-SERVER-IP:PORT/;
            proxy_redirect     off;
            proxy_set_header   Host             OVH-SERVER-IP;
            proxy_set_header   X-Real-IP        $remote_addr;
            proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;
            client_max_body_size       10m;
            client_body_buffer_size    128k;
            proxy_connect_timeout      90;
            proxy_send_timeout         90;
            proxy_read_timeout         90;
            proxy_buffer_size          4k;
            proxy_buffers              4 32k;
            proxy_busy_buffers_size    64k;
            proxy_temp_file_write_size 64k;
        }
    }
server {
        listen  80;
        server_name www.DOMAIN.COM;
        location / {
         rewrite  ^(.*)$  http://DOMAIN.COM$1 permanent;
         access_log   off;
        }
}

Am Mainserver kann die Original User IP zb. für Foren Bans aus dem $remote_addr header ausgelesen werden, falls ein Proxy benutzt wird kann dessen IP aus $proxy_add_x_forwarded_for Header ausgelesen worden.
Über proxy_pass kann die verbindung zum Mainserver auch komplett über SSL Abgewickelt werden, dazu einfach http:// zu https:// wechseln.

Über weitere Parameter kann der Proxy auch Bilder/Videos/Stylesheets Cachen – dazu Hier ein guter Artikel.

Fazit:
Sehr effektiv um Kosten zu sparen, und gleichzeitig auch der Vorteil des schnellen Wechsels: Mit diesem Setup kann man Problemlos einen Zweiten Proxy als Backup Online halten und falls Abuse eintrifft und der Proxy down geht einfach im DNS wechseln – kombiniert mit einer TTL von zB. 10 Minuten ist Downtime somit fast 0.

This entry was posted in Uncategorized. Bookmark the permalink.

27 thoughts on “[Tutorial] Nginx als Reverse Proxy

  1. www-rewrite besser so machen, das wird schneller:

    server {
    listen 80;
    server_name DOMAIN.COM;
    ...
    }
    server {
    listen 80;
    server_name www.DOMAIN.COM;
    location / {
    rewrite ^(.*)$ http://DOMAIN.COM$1 permanent;
    access_log off;
    }
    }

    Und nicht zu vergessen in OVH-SERVER “set_real_ip_from” zu addieren:

    server {
    listen 80;
    server_name www.DOMAIN.COM;
    set_real_ip_from IP-OFFSCHORE-SERVER;
    ...
    }

  2. Exakt so würde ich es auch machen, und exakt so bin, ich es theoretisch auch schon einige male durchgegangen.

    Nur sind meine Projekte derart klein, das es sich nicht lohnt, so ein Aufwand zu mahcen. Da ein kleiner VPS das locker auch kann.

  3. Hey, kannst du mal ein Tutorial machen wie man ein “Daily FULL Server Backup” macht und wie man es nochmal auf den Hauptserver aufspielt?
    All deiner Howto’s habe ich verstanden nicht so wie bei anderen.

    Weiter so!!

  4. naja, nicht wirklich – Full backups am besten wenn der Server aus ist, oder via Rsync.
    Wobei ich leider von beidem wenig Ahnung habe, also wird das Tutorial wohl leider nicht kommen 🙁

    @Alrond: I added/changed it, thanks

  5. @backup schau dir einfach mal “duplicity” an, dann schickt auch ein fullbackup im monat oder woche und sonst inkrementell.

  6. Hey,
    kannst du mal schauen, ob du ein Tutorial für Cpanel mit Nginx (Nginx Admin, http://nginxcp.com/) hinbekommst?
    Wäre dann ja folgender Aufbau:
    PC -> Offshore-Server -> OVH Nginx -> OVH Apache

    oder andersrum:
    Offshore Server <- OVH Apache <- OVH Nginx <- PC

  7. Nicht wirklich, da mir einfach die Cpanel Lizenz fehlt bzw ich von Control Panels generell wenig halte.

  8. Danke für den Tutorial.

    Ich mache da offensichtlich etwas falsch… Ich bekomme immer Bad gateway 502 und in meinem nginx error.log stehen diese: connect() failed (110: Connection timed out) while connecting to upstream, client: CLIENT_IP_REMOVED, server: MYDOMAIN-REMOVED, request: “GET / HTTP/1.1”, upstream: “http://SERVER-IP-REMOVED:80/”, host: “MYDOMAIN-REMOVED”.

    Muss ich da am Apache auf dem Zielserver was einstellen? Direkter Zugriff auf den Zielserver funktioinert ohne Probleme.

    Ich bedanke mich für weitere Hinweise.

  9. Auf dem Zielserver läuft keine FW und port 80 stimmt auch :s

    Ich habe es mit den gleichen Einstellungen auf einem anderen VPS versucht, und da funkzioinert alles super.

    Also..
    Proxy VPS bei Hetzner -> Zielserver geht,
    Proxy VPS bei Heihachi -> Zielserver geht garnicht.

    Kann es sei, dass Heihachi da was blockiert?

  10. Kannst du den Zielserver von Heihachi aus anpingen?

    Würde mich wenig wundern wenn der ISP gnadenlos alles an Heihachi IP Space nullrouted.

  11. Hi Will.

    Genau das war das Problem, meine Heichachi IP ist bei Hetzner offensichtlich null-routed. Die beiden Zielserver, mit denen ich es versucht habe. Jetzt habe ich es mit einem anderen Provider versucht und da klappt es wunderbar.

    Noch eine Frage, wenn ich darf. Ist dass eine “Bulletproof” Tarnung oder kann man irgendwie die IP des Zielservers rauskriegen (abgesehen davon, dass man sich selbst verraet via server name oder server tokens?)

    Und noch wass… Diese Methode sollte eigentlich den Zielserver um einiges sicherer machen, da die richtige IP der “Aussenwelt” nicht mitgeteilt wird, oder irre ich mich da?

  12. Dachte ich mir.

    Im Normalfall sollte keiner so leicht an die echte IP kommen, wenn man aber zB. ein Systeminfo Script einfügt, oder per PHP die externe IP des Servers ausgeben lässt kommt klarerweise die echte IP raus.

    “Sicher” ist per Definition gar nichts,
    unsichere PHP Skripte können noch immer den Realen Server exploiten.
    Der Vorteil liegt mmn. vor allem beim DDoS “Schutz” – Proxy switchen und die Attacke geht ins nichts (sofern sie IP Target war, und nicht Domain).

  13. Kurze Frage.

    Ist es möglich das ganze auch für https zu realisieren? Das er jeweils Ganz normal http und https durchlässt?

    Ein ausfürhliches Howto würde mich sehr Interessieren.

  14. Natürlich – Du kannst es auch hier direkt testen: der Blog ist via HTTPS und HTTP erreichbar, backend technisch geht HTTP über HTTP zum backend, und HTTPS über HTTPS.

    Schau dir einfach einmal normale nginx Tutorials für SSL an – du musst nur den Port ändern und das Zertifikat einbinden, der Rest (Proxy zum backend) bleibt 1:1 gleich.

    Beachte aber das zB. WordPress damit Probleme hat und das jeweils die SSL connection über SSL zum backend gehen muss, die HTTP connection aber über HTTP – sonst werden Stylesheets/Bilder/etc nicht geladen über HTTP.

  15. Danke für die schnelle Antwort.
    Ich dachte bei mir eigentlich eher an ein torrentrackerprojekt das bald Online gehen soll. Um den Spass ein wenig schwiriger für Gewisse kreise zu gestalten. Meinst das würde funktionieren?

  16. Kurze unwissende aber für mich interessante Frage.

    Du hast ja geschrieben:

    OVH Root = 1,5TB Traffic
    Offshore VPS = 200GB Traffic

    An welcher Stelle wird nun der Traffic erzeugt ?? Auf dem OVH Root auf dem die Files liegen oder auf beiden gleichermassen ? Sprich nach 200GB Traffic währe ffektiv schluss ?

  17. Hallo,

    es gibt hier ein kleines Nginx Problem, vielleicht ist mein Verstaendnis einfach nur falsch ..

    Ich habe in einer DMZ einen Server, welcher einen Virtual Host mit einem nicht oeffentlichem Hostnamen beinhaltet:
    public.bla.intern
    Vor diesem Server steht ein nginx mit einem oeffentlichem Hostname
    public.bla.com

    Nun ist der DMZ Server leider ein name based virtual host und ich kann den korrekten internenen Hostnamen leider nicht weitergeben –> mit einem redirect ist mir also nicht geholfen.

    Weisst du hier zufaellig weiter oder verrenne ich mich hier ?
    Das Umbennen des virtual host ist leider keine Loesung, da an dem Server mehr haengt 🙁

    Danke fuer die Hilfe
    Gruss
    Michael

  18. Zusatz zum Post von eben ….

    Wir reden hier von HTTPS Servern ….

    nochmal Danke ^^
    Gruss
    Michael

  19. @Cloud: Auf beiden – eigentlich x2, der Offshore Server hat zb. 1Gb Incoming, dann 1Gb weiter zu OVH.

    @Michael:
    Sorry, keine Ahnung….

Comments are closed.