F5 webd, aka. nginx

Fun fact…

On BIG-IQ/BIG-IQ based platforms, such as iWorkflow, F5 are rebuilding nginx and trying to disguise the fact by called it "webd".

On iWorkflow, nginx aka. webd, is used to serve up static content and reverse proxy to node.js and the java monstrosity that seems to provide most of the core iWorkflow functionality.

Apache has long been used on BIG-IP platforms in this way, and even with v13.1.0, Apache is still used for this purpose; with the management webUI provided primarily by a Tomcat/Java web app that Apache reverse proxies too.

The switch from Apache to nginx is... interesting... and kind of shocking that they're trying to hide it.

[[email protected]:Active:Standalone] ~ # rpm -qi -f /usr/bin/webd
Name        : webd                         Relocations: (not relocatable)
Version     : 1.10.1                            Vendor: F5 Networks, Inc.
Release     : 0.0.10791                     Build Date: Thu 24 Aug 2017 12:42:28 PM AEST
Install Date: Thu 24 Aug 2017 10:40:43 PM AEST      Build Host: build34
Group       : Development/Libraries         Source RPM: webd-1.10.1-0.0.10791.src.rpm
Size        : 1062702                          License: BSD-like
Signature   : (none)
Packager    : F5
Summary     : webd is a high-performance HTTP server and reverse proxy.
Description :
webd is a free, open-source, high-performance HTTP server and reverse proxy
[[email protected]:Active:Standalone] ~ # rpm -ql webd
/etc/bigstart/scripts/webd
/etc/fastcgi.conf
/etc/fastcgi_params
/etc/logrotate.d/webd
/etc/uwsgi_params
/etc/webd/mime.types
/etc/webd/webd.conf
/usr/bin/webd
/usr/lib/webd/lua/authenticateauth.lua
/usr/lib/webd/lua/authutil.lua
/usr/lib/webd/lua/cjson.so
/usr/lib/webd/lua/icauth.lua
/usr/lib/webd/lua/restauth.lua
[[email protected]:Active:Standalone] ~ #
[[email protected]:Active:Standalone] ~ # strings /usr/bin/webd | grep -i nginx\ version
nginx version: webd/1.10.1
[[email protected]:Active:Standalone] ~ #
[[email protected]:Active:Standalone] ~ # cat /etc/webd/webd.conf
# F5 webd configuration file

user apache;

# run in the foreground so bigstart can control the process
daemon off;

worker_processes auto;
worker_rlimit_nofile 8192;
events {
    worker_connections 4096;
}

error_log /var/log/webd/errors.log notice;

http {
    lua_package_cpath '/usr/lib/webd/lua/?.so;;';
    lua_package_path '/usr/lib/webd/lua/?.lua;;';

    include mime.types;
    default_type application/octet-stream;
    sendfile on;
    keepalive_timeout 65;
    gzip on;
    etag on;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';
    access_log /var/log/webd/access.log main;
    client_body_temp_path /var/run/webd/body_temp 1 2;
    proxy_temp_path /var/run/webd/proxy_temp 1 2;
    proxy_buffers 16 64k;
    fastcgi_temp_path /var/run/webd/fastcgi_temp 1 2;
    fastcgi_buffers 16 64k;
    client_max_body_size 16M;

    upstream rest {
        server 127.0.0.1:8100;
    }

    upstream node {
        server 127.0.0.1:8200;
    }

    server {
        listen 80;

        # don't expose server version
        server_tokens off;

        # redirect UI requests to https
        location = / {
            return 301 https://$http_host$request_uri;
        }

        location /ui {
            return 301 https://$http_host$request_uri;
        }
    }

    # expose /restui to proxy internal worker presentation and table of contents requests.
    # restjavad uses webd headers in client response so that proper UI-oriented caching behavior is achieved.
    server {
        listen 127.0.0.1:80;

        location /restui {
            root /usr/local/www;
            try_files $uri $uri/ index.html;
        }

        # iControl FastCGI endpoint
        # listen on http:80 for local requests
        location /iControl/iControlPortal.cgi {
            access_by_lua_file /usr/lib/webd/lua/icauth.lua;
            fastcgi_pass            127.0.0.1:8202;
            fastcgi_pass_header     X-IControl-Session;
            fastcgi_pass_request_body       on;
            fastcgi_param  QUERY_STRING     $query_string;
            fastcgi_param  REQUEST_METHOD   $request_method;
            fastcgi_param  CONTENT_TYPE     $content_type;
            fastcgi_param  CONTENT_LENGTH   $content_length;
            fastcgi_param  SCRIPT_NAME      '/iControl/iControlPortal.cgi';
        }
    }

    server {
        listen [::]:443 ipv6only=on ssl;
        listen *:443 ssl;

        # don't expose server version
        server_tokens off;

        ssl_certificate /etc/httpd/conf/ssl.crt/server.crt;
        ssl_certificate_key /etc/httpd/conf/ssl.key/server.key;
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;
        ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA;

        # catch HTTP error 497 (HTTP Request Sent to HTTPS Port) and redirect to HTTPS
        error_page 497 https://$http_host$request_uri;

        # socket.io websocket syncserver:
        #   /socket.io: client and metadata
        #   /sync: actual websocket data communication
        location ~ ^/(sync|socket\.io) {
            proxy_redirect          off;
            proxy_pass              http://node;
            proxy_http_version      1.1;
            proxy_set_header        Upgrade             $http_upgrade;
            proxy_set_header        Connection          "upgrade";
            proxy_set_header        Host                $http_host;
            proxy_set_header        X-nginx-proxy       true;
            proxy_set_header        X-Real-IP           $remote_addr;
            proxy_set_header        X-Forwarded-For     $proxy_add_x_forwarded_for;
        }

        # static assets
        location /ui {
            root /usr/local/www;
            try_files $uri $uri/ index.html;
            add_header X-Frame-Options                  SAMEORIGIN;
            add_header X-Content-Type-Options           nosniff;
            add_header X-XSS-Protection                 "1; mode=block";
            add_header Cache-Control                    "no-cache";

            # Content Security Policy headers are disabled currently because they prevent PhantomJS/CasperJS from working
            # # Content Security Policy: Chrome <25, Safari <7
            # add_header X-Webkit-CSP                   "default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline';";

            # # Content Security Policy: Firefox <23, IE 10,11
            # add_header X-Content-Security-Policy      "default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline';";

            # # Content Security Policy: official W3C header (modern browsers)
            # add_header Content-Security-Policy        "default-src 'self'; img-src 'self' data:; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline';";

            # tell browsers this site is meant for HTTPS only
            add_header Strict-Transport-Security        "max-age=16070400; includeSubDomains";
            add_header X-Download-Options               noopen;

            # prevent older IE browsers from running in compatibility mode, which breaks the UI badly
            add_header X-UA-Compatible                  "IE=edge";

            # pop-out help
            rewrite ^/ui/(.+?)/help$                        /ui/js/popouthelp.html break;

            # url routes for single-page angular apps (html5 navigation)
            # system
            rewrite ^/ui/system/configuration/?$            /ui/system/index-angular.html break;
            rewrite ^/ui/system/access/?$                   /ui/system/index-angular.html break;
            rewrite ^/ui/system/setup/?$                    /ui/system/index-angular.html break;

            # device
            rewrite ^/ui/device/configuration/?$            /ui/device/index-angular.html break;
            rewrite ^/ui/device/configuration/cluster/?$    /ui/device/index-angular.html break;
            rewrite ^/ui/device/provisioning/?$             /ui/device/index-angular.html break;
            rewrite ^/ui/device(/index.html|/)?$            /ui/device/index-angular.html break;

            # cloud
            rewrite ^/ui/cloud/overview/?$                  /ui/cloud/index-angular.html break;
            rewrite ^/ui/cloud(/index.html|/)?$             /ui/cloud/index-angular.html break;
        }

        # Rest UI
        location /restui {
            root /usr/local/www;
            try_files $uri $uri/ index.html;
        }

        #Serve AppsLX or Plugin custom presentation static content.
        location /iapps {
            root /usr/local/www;
            try_files $uri $uri/ index.html;
        }

        # SNMP MIBs
        location /docs {
            root /usr/local/www;
            try_files $uri $uri/ index.html;
        }

        # iControl FastCGI endpoint
        location /iControl/iControlPortal.cgi {
            access_by_lua_file /usr/lib/webd/lua/icauth.lua;
            fastcgi_pass            127.0.0.1:8202;
            fastcgi_pass_header     X-IControl-Session;
            fastcgi_pass_request_body       on;
            fastcgi_param  QUERY_STRING     $query_string;
            fastcgi_param  REQUEST_METHOD   $request_method;
            fastcgi_param  CONTENT_TYPE     $content_type;
            fastcgi_param  CONTENT_LENGTH   $content_length;
            fastcgi_param  SCRIPT_NAME      '/iControl/iControlPortal.cgi';
        }

        # proxy requests to the REST framework
        location /mgmt {
            access_by_lua_file /usr/lib/webd/lua/restauth.lua;
            proxy_set_header        Host                localhost:8100;
            proxy_set_header        X-Real-IP           $remote_addr;
            proxy_set_header        X-Forwarded-For     $proxy_add_x_forwarded_for;
            proxy_set_header        Connection          keep-alive;
            proxy_connect_timeout   5s;
            proxy_read_timeout      300s;
            proxy_pass              http://rest;

            # Special handling for /mgmt/shared/authn/login
            # Always submit a login request as admin since the user/pass is in the
            # JSON payload.   The REST framework expects a valid username in the
            # authenticate header, but since this is a login attempt, there is no
            # user set yet
            # TODO - when the token auth header is defined, we'll need to clear it here too
            location /mgmt/shared/authn/login {
                access_by_lua_file /usr/lib/webd/lua/authenticateauth.lua;
                proxy_pass          http://rest;
            }
        }

        # proxy requests to Node
        location /info {
            proxy_pass              http://node;
            proxy_set_header        Host                $hostname:$proxy_port;
            proxy_set_header        X-Real-IP           $remote_addr;
            proxy_set_header        X-Forwarded-For     $proxy_add_x_forwarded_for;
            proxy_set_header        Connection          keep-alive;
            proxy_connect_timeout   5s;
            proxy_read_timeout      300s;
        }

        # redirect /ui and / to the login URI
        location ~* ^/(ui/)?$ {
            port_in_redirect off;
            return 301 https://$http_host/ui/login/;
        }

        # F5 Automated Deployment
        #
        # This location will symlink to /mnt/images, which is where ISOs will be
        # loop mounted for PXE installs.
        location /images {
            root /mnt;
        }

        location /favicon.ico {
            root /usr/local/www;
        }

        location /robots.txt {
            root /usr/local/www;
        }
    }
}
[[email protected]:Active:Standalone] ~ #
Author image
About Colin Stubbs
Brisbane, Queensland, Australia
Space monkey meat popsicle with technology and noise addictions.