Mani digitālie lauki

Emuārs par darbiem, nedarbiem u.c. lietām, kuras gribas publiski pierakstīt.
en lv

Reversais proxy publiskiem mājas web servisiem

OpenWrt man jau kādu labu laiku ir standarts maniem tikla rūteriem. Faktiski tiek pirkti tikai tādi, uz kuriem darbojas OpenWrt un attiecīgi nomainīta orģinālā mašīnprogrammatūra (firmware) pret OpenWrt. Izņēmums ir laukos LMT Mikrotik rūteris, kur samierinos ar kaut kādā ziņā vietējā ražojuma slēgtā koda RouterOS.

Tad nu ir virkne ierīces ar web servisiem, kas ir lokālajā tīklā un kurus ir vērts atvērt piekļuvei publiskajā tīklā. Piemēram šis mans personiskais web serveris emuāram, kāds RTL SDR uztvērējs, kas klausāms un darbināms caur web serveri u.tml. Labu laiku iztiku ar vienkāršu portu pārvirzīšanu, kas uz OpenWrt ir samērā vienkāršs pasākums. Te gan ir ierobežojumi. Piemēram: uz rūtera izejošā porta varu nokonfigurēt priekš savam emuāra web servera moklusēto 80 portu un man tas atbilstoši strādās interneta pārlūkā ierakstot tikai emuāra addresi, savukārt citam web servisam man uz rūtera būs jāatver cits ports un tas jāatceras un pārlūkā jāieraksta kopā ar manu domēnvārda addresi. Tas nav īpaši ērti un tos porta ciparus bieži nojauc, piemirst u.tml.

Tad nu radās doma, ka jābūt kādai iespējai iestāstīt tam rūterim, ka dažādas apakšdomēna adreses darbosies caur rūteri ar dažādām lokālā tikla addresēm (web serveriem). Biki parokoties un pajautājot OpenWrt forumā tika noskaidrots, ka vajadzīgā lieta saucas reverse proxy. Un konkrētā gadījumā ir izmantots nginx.

Nepieciešmās priekšzināšanas:

  • datortīklošanās pamati (IP addreses, porti, publiskie un lokālie tīkli u.tml.),
  • darbs ar komandrindu,
  • kā pieslēgties attalinātam datoram/ierīcei izmantojot SSH,
  • pamatdarbības ar OpenWrt. T.i. ja esiet spējuši uzdabūt uz sava rūtera OpenWrt, tad ticami, ka būsiet spējīgi arī tikt galā ar šo… ;-)

Zemāk soli pa solim, kā to uzstādīt uz OpenWrt

1) Izmantojam ssh piekļuvi un pievienojamies savam OpenWrt rūterim. No windows datora varam izmantot putty, bet no linukša, būs kaut kā tā:

ssh user@192.168.1.1

Protams koriģējot lietotāju un IP addresi atbilstoši savai situācijai.

2) Atjaunojam OpenWrt instalācijas pakotņu sarakstu un uzinstalējam nginx:

opkg update
opkg install nginx

3) Par cik uz 80 porta jau “sēž” OpenWrt web administrācjas severis, tad pārkonfigurējam to uz citu:

vi /etc/config/uhttpd

un nomainam portus 80 uz 8080 u.tml.:

config uhttpd 'main'
        list listen_http '192.168.1.1:8080'
        list listen_http '[::]:8080'
        list listen_https '192.168.1.1:8443'
        list listen_https '[::]:8443'
        option home '/www'
        option rfc1918_filter '1'
...

Pārlādējam web administrācijas paneļa web servisu:

/etc/init.d/uhttpd reload

… un web caurlūkprogrammā pārliecinamies, ka tiekam tam klāt caur nomainīto portu (piem šinī piemērā tas būtu: http://192.168.1.1:8080).

uci set nginx.global.uci_enable=false

4) Atveram /etc/nginx/nginx.conf datni

vi /etc/nginx/nginx.conf

un papildinām http bloku ar atbilstošiem server apakšblokiem. Dotajā datnē ir aizkomentēti sakarīgi piemēri, ko arī var palasīt un izmantot, bet mums šinī gadījumā ir vajadzīgs kaut kas šāds:

server {
    listen 80;
    server_name www.domens.mans;
        location / {
          # app1 reverse proxy
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_pass http://192.168.1.33:80;
        }

   access_log      /var/log/nginx/www.domens.mans_access.log;
   error_log       /var/log/nginx/www.domens.mans_error.log;

}

server {
    listen 80;
    server_name sdr.domens.mans;
        location / {
          # app1 reverse proxy
          proxy_set_header X-Real-IP $remote_addr;
          proxy_set_header Host $host;
          proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
          proxy_pass http://192.168.1.55:5000;
        }

   access_log      /var/log/nginx/sdr.domens.mans_access.log;
   error_log       /var/log/nginx/sdr.domens.mans_error.log;

}

, kur svarīgākās vietas ir server_name (servera domēnvārds / addrese, ko izmantosim izsaucot web browserī) un proxy_pass (arbilstošā web servera lokalā tikla addrese). Vēl te ir labas iespējas, ka var izmantot ar web servera apakš direktorijas t.i. lokalājā tīklā var būt vairāki web servisi uz viena web servera sadalīti pa apakšmapēm, savukārt publiskajā internetā tie izsaucami katrs ar savu domēnvārdu/addresi. Tāpat arī otrādi.

Šī soļa beigās varam palaist nginx servisu un pārbaudīt kā tas darbojas lokālajā tīklā. T.i. palaižot komandu:

/etc/init.d/nginx start

T.i. ja komanda neatrgriež nekādus kļūdu paziņojumus, tad šīm konfigurācijām jau būtu jābūt spēkā esot lokālajā tīklā un to var parbaudīt izmantojot caurlūkprogrammu vai komandrindā ar wget, vai curl.

5) Tomēr no publiskā interneta tas vēl nedarbosies. Es to parasti pārbaudu uz telefona izslēdzot WiFi, vai caur datoru pieslēdzoties pie kāda attālināta VPN. Lai tas darbotos arī publiskajā internetā, tad nepieciešama atbilstoša nosacījuma konfigurēšana ugunsmūrī, lai dotu pieeju atbilstošajam nginx portam.

Labojam datni:

vi /etc/config/firewall 

papildinam ar atbilstošu sadaļu:

config rule
        option enabled '1'                      
        option target 'ACCEPT'                  
        option src 'wan'                        
        option dest_port '80'                   
        option proto 'tcp udp'                  
        option name 'NginxRevProxyHttp'  

Pēc šī pārlādējam ugunsmūra konfigurāciju:

/etc/init.d/firewall reload

Šo gan var krietni vienkāršak un ātrāk izdarīt caur OpenWrt web konfigurācijas saskarni sadaļā Network -> Firewall -> Trafic Rules -> Forma “New forward rule”

Tagad varam pārbaudīt veicot web servisa vaicājumsu no publiskā interneta puses.

6) Ja viss darbojas, kā paredzēts, tad paliek pēdējais solis ieslēgt nginx servisu patstavīgi, lai tas pie rūtera restarta palaistos automātiski:

/etc/init.d/nginx enable

Tas pamatā arī viss - iesākumam.

Tālākiem smukumiem varētu būt vērts sakonfigurēt, tā lai tas strādā arī ar HTTPS, bet tas jau nedaudz cits stāsts… ;-)