Skip to main content

Using an Ad-Hoc Nginx Server to Catch-Web Requests

Set up Custom Logging

sudo apt install -y libnginx-mod-http-lua

Install Nginx LUA libraries

sudo nano /etc/nginx/nginx.conf.d/header_logging.conf

Edit the Nginx configuration file

http {

# ...
# ...
# ...

  
    log_format custom  'Time: $time_local'

                      '
'
                      'Remote Addr: $remote_addr'
                      '
'
                      'Request: $request'
                      '
'
                      'Request Headers: $request_headers'
                      '
'
                      'Body: $request_body'
                      '
'
                      'Status: $status'
                      '
'
                      '-----';

# ...
# ...
# ...
  
}

Add a custom logging format using LUA script

Define an Ad-Hoc Server

sudo nano /etc/nginx/sites-available/ad-hoc.conf

Create a configuration file for the ad-hoc server

server {
    # Replace listener_ip_goes_here with the IP you wish to listen on
    server_name listener_ip_goes_here;
    listen 80;
    
    root /tmp/ad-hoc;
    index index.html;
    # Uncomment to allow directory listing
    # autoindex on;
    
    ##
    # LUA Advanced Logging
    ##
  
    # Lua script to scrape and format the headers
    set_by_lua_block $request_headers {
        local h = ngx.req.get_headers()
        local request_headers_all = ""
        for k, v in pairs(h) do
            request_headers_all = request_headers_all .. ""..k..": "..v..";"
        end
        return request_headers_all
    }
    
    access_log /tmp/ad-hoc/access_verbose.log custom;
    
    location / {
        try_files $uri $uri/ =404;
    }
}

ad-hoc.conf

Enable the Configuration

mkdir /tmp/ad-hoc
sudo ln -s /etc/nginx/sites-available/ad-hoc.conf /etc/nginx/sites-enabled/ad-hoc.conf
sudo nginx -t && sudo systemctl restart nginx

Making any changes to ad-hoc.conf should be done on /etc/nginx/sites-available/ad-hoc.confDO NOT edit the symbolically linked file.

Making any changes will also require a service restart using sudo systemctl restart nginx.

tail -fn 0 /tmp/ad-hoc/access_verbose.log

Monitor the verbose access logs as they come in

Automate Setup/Teardown

You can add this function to your shell .rc file and call the adhoc_nginx function as needed

Show / Hide Code Block
function adhoc_nginx () {

  local INDEX_HTML='<h1>Hello, world!</h1>'
  local START_USAGE="Usage: $0 start <config_name.conf> <listener_ip|listener_fqdn> <listener_port>"
  local STOP_USAGE="Usage: $0 stop <config_name.conf> [--destroy-web-root|-d]"
  local NGINX_BASEDIR="/etc/nginx"
  local NGINX_AVAILABLE_BASEDIR="${NGINX_BASEDIR}/sites-available"
  local NGINX_ENABLED_BASEDIR="${NGINX_BASEDIR}/sites-enabled"
  local NGINX_DEFAULT_ENABLED="${NGINX_ENABLED_BASEDIR}/default"
  local LUA_LOGGING_CONF="${NGINX_BASEDIR}/conf.d/lua_logging.conf"
  local ACTION=$(echo "$1" | tr '[:upper:]' '[:lower:]' 2>/dev/null)
  local CONFIG_NAME=$2
  local CONFIG_FILE_AVAILABLE="${NGINX_AVAILABLE_BASEDIR}/${CONFIG_NAME}"
  local CONFIG_FILE_ENABLED="${NGINX_ENABLED_BASEDIR}/${CONFIG_NAME}"

  case "$ACTION" in
    start|stop)
      # valid action, continue to processing below
      ;;
    help|-h|--help|"")
      echo "$START_USAGE"
      echo "$STOP_USAGE"
      return
      ;;
    *)
      echo "$START_USAGE"
      echo "$STOP_USAGE"
      return
      ;;
  esac

  if [ "$ACTION" == "stop" ] ; then

    if [ $# -lt 2 ] || [ $# -gt 3 ] ; then

      echo "$STOP_USAGE"
      return

    else

      if [ $# -eq 3 ] ; then
        local DESTROY=$(echo "$3" | tr '[:upper:]' '[:lower:]' 2>/dev/null)
        if [ "$DESTROY" != '--destroy-web-root' ] && [ "$DESTROY" != '-d' ] ; then
          echo "$STOP_USAGE"
          return
        else
          DESTROY=true
        fi
      fi
      
      if ! [ -f "$CONFIG_FILE_AVAILABLE" ] && ! [ -f "$CONFIG_FILE_ENABLED" ] ; then
        echo "[-]  Config file not found either of these paths:"
        echo "     \"${CONFIG_FILE_AVAILABLE}\""
        echo "     \"${CONFIG_FILE_ENABLED}\""
        return
      else

        sudo /usr/bin/systemctl stop nginx >/dev/null 2>&1
        if [ $? -eq 0 ] ; then
          echo "[+]  Nginx service stopped"
        else
          echo "[-]  Could not stop Nginx service, exiting"
          return
        fi

        local WEB_ROOT=$(/usr/bin/grep -E '^\s{1,}root' "$CONFIG_FILE_ENABLED" | awk -v FS=' ' '{print $2}' | tr -d ';')
        if [ "$DESTROY" == true ] ; then
          if [ -d "$WEB_ROOT" ] ; then
            rm -rf "$WEB_ROOT" >/dev/null 2>&1
            if [ $? -eq 0 ] ; then
              echo "[+]  Deleted web root: ${WEB_ROOT}"
            else
              echo "[+]  Unable to delete web root: \"${WEB_ROOT}\""
            fi
          fi

        else
          echo "[*]  Web root preserved: \"${WEB_ROOT}\""
        fi

        sudo rm -f "$CONFIG_FILE_AVAILABLE" >/dev/null 2>&1
        if ! [ $? -eq 0 ] ; then
          echo "[-]  Unable to remove \"${CONFIG_FILE_AVAILABLE}\", please remove manually."
        fi
        
        sudo rm -f "$CONFIG_FILE_ENABLED" >/dev/null 2>&1
        if ! [ $? -eq 0 ] ; then
          echo "[-]  Unable to remove \"${CONFIG_FILE_ENABLED}\", please remove manually."
        fi
        
        return

      fi
    
    fi
    
  fi

  if [ "$ACTION" == "start" ] ; then

    NGINX_LUA_LIB=$(/usr/bin/dpkg -l | /usr/bin/grep -o "libnginx-mod-http-lua")
    if [ $# -ne 4 ] ; then
      echo "$START_USAGE"
      return
    elif [ -z "$NGINX_LUA_LIB" ] ; then
      echo "[-]  Nginx Lua module not installed"
      echo "[*]  Install with \"apt install libnginx-mod-http-lua\""
      echo "[*]  Exiting"
      return
    else

      local SERVER_NAME=$3
      local SERVER_PORT=$4
      local WEB_ROOT="/tmp/${CONFIG_NAME}"
      local CHECK_PORT=$(sudo ss -lptn "sport = :${SERVER_PORT}" | grep "${SERVER_PORT}" | awk -v FS=' ' '{print $4 " " $6}')
      
      if [ "$SERVER_PORT" -lt 1 ] || [ "$SERVER_PORT" -gt 65535 ] ; then
        echo "[-]  Choose a valide TCP port between 1-65535"
        return
      fi

      if [ -n "$CHECK_PORT" ] ; then
        echo "[-]  TCP port ${SERVER_PORT} already bound by another process"
        echo "      $CHECK_PORT"
        return
      fi

      if [ -f "$NGINX_DEFAULT_ENABLED" ] ; then
        echo "[-]  Default Nginx configuration enabled, which may interfere with this server"
        echo "[-]  Unlink ${NGINX_DEFAULT_ENABLED} and try again"
        return
      fi
      
      # Create Lua logging configuration
cat << 'EOF' | sudo tee "$LUA_LOGGING_CONF" >/dev/null 2>&1
log_format custom  'Time: $time_local'

                  '
'
                  'Remote Addr: $remote_addr'
                  '
'
                  'Request: $request'
                  '
'
                  'Request Headers: $request_headers'
                  '
'
                  'Body: $request_body'
                  '
'
                  'Status: $status'
                  '
'
                  '-----';
EOF

      if [ $? == 0 ] ; then
        echo "[+]  Created Lua verbose logging configuration: \"${LUA_LOGGING_CONF}\""
      else
        echo "[-]  Could not create Lua verbose logging configuration: \"${LUA_LOGGING_CONF}\", exiting"
        return
      fi

      if [ -f "$CONFIG_FILE_AVAILABLE" ] && [ -f "$CONFIG_FILE_ENABLED" ] ; then
        echo "[-]  Configuration name \"${CONFIG_NAME}\" already exists, choose another"
        return
      fi

      mkdir -p "$WEB_ROOT" >/dev/null 2>&1
      if [ $? -eq 0 ] ; then
        echo "[+]  Successfully created web root: \"${WEB_ROOT}\""
        echo "${INDEX_HTML}" > "${WEB_ROOT}/index.html"
        echo "[*]  Added dummy site index to: \"${WEB_ROOT}/index.html\""
      else
        echo "[-]  Unable to create web root: \"${WEB_ROOT}\", exiting"
        return
      fi

cat << 'EOF' | sed -e "s|{{LISTENER_PLACEHOLDER}}|${SERVER_NAME}|g" \
-e "s|{{PORT_PLACEHOLDER}}|${SERVER_PORT}|g" \
-e "s|{{WEB_ROOT_PLACEHOLDER}}|${WEB_ROOT}|g" | sudo tee "$CONFIG_FILE_AVAILABLE" >/dev/null 2>&1
server {
    server_name {{LISTENER_PLACEHOLDER}} default;
    listen {{PORT_PLACEHOLDER}};

    root {{WEB_ROOT_PLACEHOLDER}};
    index index.html;
    # Uncomment to allow directory listing
    # autoindex on;

    ##
    # LUA Advanced Logging
    ##

    # Lua script to scrape and format the headers
    set_by_lua_block $request_headers {
        local h = ngx.req.get_headers()
        local request_headers_all = ""
        for k, v in pairs(h) do
            request_headers_all = request_headers_all .. ""..k..": "..v..";"
        end
        return request_headers_all
    }

    access_log {{WEB_ROOT_PLACEHOLDER}}/access_verbose.log custom;

    location / {
        try_files $uri $uri/ =404;
    }
}
EOF

      if [ $? -eq 0 ] ; then
        echo "[+]  Successfully added Nginx server config: \"${CONFIG_FILE_AVAILABLE}\""
      else
        echo "[-]  Unable to add Nginx server config: \"${CONFIG_FILE_AVAILABLE}\", exiting"
        return
      fi

      sudo ln -s "$CONFIG_FILE_AVAILABLE" "$CONFIG_FILE_ENABLED" >/dev/null 2>&1
      if [ $? -eq 0 ] ; then
        echo "[+]  Symbollically linked \"${CONFIG_FILE_AVAILABLE}\" to \"${CONFIG_FILE_ENABLED}\""
      else
        echo "[-]  Unable to symbolically link \"${CONFIG_FILE_AVAILABLE}\" to \"${CONFIG_FILE_ENABLED}\", exiting."
        return
      fi

      sudo /usr/sbin/nginx -t >/dev/null 2>&1 && sudo /usr/bin/systemctl start nginx >/dev/null 2>&1
      if [ $? -eq 0 ] ; then
        echo "[+]  Started Nginx service"
        echo "[*]  Please verify connectivity to your web server"
        echo "[*]  Add any HTML / web application files to \"${WEB_ROOT}/\""
        echo "[*]  Modify the Nginx config as needed at: \"${CONFIG_FILE_AVAILABLE}\""
        echo "[*]  Then, run 'sudo systemctl restart nginx'"
      else
        echo "[-]  Unable to start Nginx service, exiting."
        echo "[*]  Troubleshoot by running \"nginx -t\" and \"journalctl -xeu nginx\""
        return
      fi

    fi

  fi

}

image.png

Showing some example output from the function

image.png

Connectivity works

image.png

Verbose Lua logging also works as expected