Category: Linux

  • Apache 2.4.64, SNI, and 421 Misdirected Request: cause and fix

    After upgrading to Apache 2.4.64 (or after applying linux vendors updates) many sites behind a reverse proxy started returning 421 Misdirected Request. The practical cause is simple: when your proxy makes an HTTPS connection to Apache, Apache now expects a correct TLS SNI value that matches the HTTP host. If the proxy omits SNI or sends a different name than the Host header, Apache can reject the request with 421. This change exposed default proxy settings that used to work by accident.

    What the 421 error means

    The HTTP 421 Misdirected Request status means the request reached a server that is not configured to respond for the combination of scheme and authority that you used. Browsers often reuse HTTP/2 connections across hosts if the server allows it, but Apache 2.4.64 tightened the checks so that connections without a matching SNI and Host are rejected. That is why you can see the error only on some requests or only on some subdomains after the update. The error message is the following:

    Misdirected Request

    The client needs a new connection for this request as the requested host name does not match the Server Name Indication (SNI) in use for this connection.

    Who is affected

    You are affected if a reverse proxy connects to Apache over HTTPS and does not pass SNI to the backend. This is common for nginx in front of Apache, HAProxy with HTTPS backends, and some CDNs or load balancers that re-encrypt to the origin. Panels that pair nginx and Apache (for example EA-Nginx on cPanel, Plesk, Hestia, and similar) were among the first to report 421 after the update.

    Fix: send the correct SNI to Apache and keep it consistent with Host

    The fix is to enable SNI on the upstream HTTPS hop and make its value match the HTTP Host that Apache should serve. Keep the connection private (VPC, VLAN, VPN, or same host) if you do not want the name visible outside your network. Do not roll back the Apache security update. Configure your proxy once and the 421 errors stop.

    nginx to Apache over HTTPS

    Enable SNI toward the backend and keep Host consistent.

    location / {
        proxy_pass              https://backend.example.com;
        proxy_set_header        Host $host;
        proxy_ssl_server_name   on;      # send SNI
        proxy_ssl_name          $host;   # SNI value
    [..]
    }

    HAProxy to Apache over HTTPS

    Pass the Host header as the SNI value on the TLS connection to Apache. Add verification settings that match your policy.

    backend app
        http-request set-header X-Forwarded-Proto https
        server app1 127.0.0.1:443 ssl sni req.hdr(Host)

    Apache to Apache with mod_proxy over HTTPS

    Use an https URL whose hostname is the site you want to serve so that Apache sends that name as SNI to the backend.

    SSLProxyEngine on
    ProxyPass        / https://site.example.com/
    ProxyPassReverse / https://site.example.com/

    How to test and confirm

    From the proxy host, curl the backend using the public hostname and the backend IP to confirm that SNI and Host agree. Watch your Apache error log for messages about missing SNI or a vhost mismatch while you test.

    curl -vk https://example.com/ --resolve example.com:443:127.0.0.1

    FAQ

    The 421 you see is produced by the stricter SNI and authority checks added around 2.4.64 and enforced by HTTP/2 handling. The cure is to send a correct SNI on the upstream connection and keep it consistent with Host.

    Do I need to verify the backend certificate for SNI to matter? No. Apache uses SNI during the TLS handshake to pick the correct SSL vhost and certificate before it even reads the HTTP request. Certificate verification by the proxy is a separate operational choice. The important part for avoiding 421 is that the SNI you send and the Host header you send resolve to the same Apache vhost.

  • Minecraft Linux Server Auto-Update

    Keeping your Minecraft Bedrock Dedicated Server up to date is essential for performance, stability, and player compatibility. In this guide, we’ll show you how to set up a lightweight Bash script that checks for new server versions and installs them, all while preserving your world and configuration files.

    Step 1: Install Dependencies

    sudo apt update
    sudo apt install curl jq unzip rsync wget

    Step 2: Create the Update Script

    Save the following as ~/update-bedrock.sh.:

    #!/usr/bin/env bash
    set -euo pipefail
    
    HOME_DIR="$HOME"
    INSTALL_DIR="$HOME_DIR/bedrock-server"
    TMP_DIR="$HOME_DIR/bedrock-tmp"
    API_URL="https://net-secondary.web.minecraft-services.net/api/v1.0/download/links"
    ZIP_NAME="bedrock.zip"
    
    command -v jq >/dev/null || { echo "jq is required"; exit 1; }
    
    echo "Fetching version info..."
    DATA=$(curl -fsSL "$API_URL")
    DOWNLOAD_URL=$(echo "$DATA" | jq -r '.result.links[] | select(.downloadType == "serverBedrockLinux") | .downloadUrl')
    VERSION=$(basename "$DOWNLOAD_URL" | grep -o '[0-9.]\+')
    
    [[ -z "$DOWNLOAD_URL" || -z "$VERSION" ]] && { echo "Failed to extract URL/version"; exit 1; }
    
    [[ -f "$INSTALL_DIR/bedrock-server.version" && "$(cat "$INSTALL_DIR/bedrock-server.version")" == "$VERSION" ]] && {
      echo "Already up to date"
      exit 0
    }
    
    mkdir -p "$TMP_DIR"
    wget -q -O "$TMP_DIR/$ZIP_NAME" "$DOWNLOAD_URL"
    unzip -t "$TMP_DIR/$ZIP_NAME" >/dev/null || { echo "ZIP test failed"; exit 1; }
    unzip -oq "$TMP_DIR/$ZIP_NAME" -d "$TMP_DIR/unpacked"
    
    [[ -x "$TMP_DIR/unpacked/bedrock_server" ]] || { echo "Missing server binary"; exit 1; }
    
    rsync -a \
      --exclude='autoupdate.sh' \
      --exclude='server.properties' \
      --exclude='permissions.json' \
      --exclude='whitelist.json' \
      --exclude='ops.json' \
      --exclude='allowlist.json' \
      --exclude='valid_known_packs.json' \
      --exclude='worlds/' \
      "$TMP_DIR/unpacked/" "$INSTALL_DIR/"
    
    echo "$VERSION" > "$INSTALL_DIR/bedrock-server.version"
    rm -rf "$TMP_DIR"
    echo "Updated to version $VERSION"
    

    Step 3: Make It Executable

    chmod +x ~/update-bedrock.sh

    Step 4: Automate with Cron (Optional)

    Edit your crontab with crontab -e and add this line to check daily at 3 AM:

    0 3 * * * ~/update-bedrock.sh >> ~/bedrock-update.log 2>&1

    Done ✅

    You now have a self-maintaining Minecraft Bedrock server that stays updated automatically!

  • Alvotech Vserver VPS with OpenVPN

    Renting a server at Alvotech and thinking about installing OpenVPN? Then follow this tutorial.

    This tutorial has been done on the default configuration of the Alvotech VPS: Debian 5 64bit, and on Debian 6 64bit.

    The specs page of the vservers show that TUN/TAP is usable, but when you rent the VPS, no TUN interface is enabled.

    The first thing is to ask the support to enable it, after they say they did, you need to reboot your server through the control panel.

    Note that you don’t need any iptable rule, ip forwarding is enabled and you cannot add any iptable rule anyway, Alvotech will enable the necessary rules on the Host.

    Then enter your server through ssh and check ifconfig, you might have something like this:

    tun2391-136 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
    inet addr:10.0.2.97 P-t-P:10.0.2.98 Mask:255.255.255.255
    UP POINTOPOINT RUNNING NOARP MULTICAST MTU:1500 Metric:1
    RX packets:11782 errors:0 dropped:0 overruns:0 frame:0
    TX packets:8389 errors:0 dropped:0 overruns:0 carrier:0
    collisions:0 txqueuelen:100
    RX bytes:1258182 (1.1 MiB) TX bytes:5467118 (5.2 MiB)

    Great, now do:

    apt-get install openvpn

    cd /etc/openvpn

    mkdir easy-rsa

    cp -r /usr/share/doc/openvpn/examples/easy-rsa/* easy-rsa/

    cd easy-rsa/2.0/

    source ./vars

    ./clean-all

    ./build-key-server server

    ./build-key client1

    ./build-dh

    ln -s /etc/openvpn/easy-rsa/2.0/keys /etc/openvpn/keys

    cd /etc/openvpn

    Now create a file server.conf with this content:

    port 1194
    proto udp
    dev tun2391-136 #Your TUN device in ifconfig
    ifconfig 10.0.2.97 10.0.2.98 # your TUN interface settings in ifconfig
    ifconfig-noexec
    route-noexec
    keepalive 10 120
    persist-key
    persist-tun
    comp-lzo
    verb 3
    fragment 1200
    mssfix 1200
    ca keys/ca.crt
    cert keys/server.crt
    key keys/server.key
    dh keys/dh1024.pem
    user nobody
    group nogroup
    tls-server
    push “dhcp-option DNS 8.8.8.8”

    Restart openvpn:

    /etc/init.d/openvpn restart

    Now copy the ca.crt client1.crt and client1.key on your client, and create a client.conf file (or client.ovpn) with this content:

    client
    dev tun
    proto udp
    remote 88.88.88.88 1194 #your server ip address/port
    resolv-retry infinite
    nobind
    persist-key
    persist-tun
    ca ca.crt
    cert client1.crt
    key client1.key
    ns-cert-type server
    comp-lzo
    verb 3
    ifconfig 10.0.2.98 10.0.2.97 #change it according to the IPs of your TUN interface, notice it is the CONTRARY of the server config
    redirect-gateway
    fragment 1200
    mssfix 1200

    And now just run “sudo openvpn client.conf”, on Windows you might need to adjust the paths to something like this: “cert c:\\Users\\admin\\desktop\\client1.crt” (for the key+certs).

    If you need another client to connect, just ask the support another TUN device (they added one on my server), copy server.conf to server2.conf, modify the TUN interface IPs/name + change the openvpn port in server2.conf, and don’t forget to generate a second client certificate!

    Enjoy!

    (thanks to the support @ Alvotech for providing the details i was missing)

  • xauth + (X11Forwarding Yes and X11UseLocalhost yes) == Still no Forwarding ?

    I was searching for this fix for quite some time. I couldn’t forward X anymore using “ssh -Y” or “ssh -X” on my debian server (i have xauth installed), i was always getting this error:

    ~$ xterm
    xterm Xt error: Can't open display:
    xterm:  DISPLAY is not set

    “X11UseLocalhost no” was making it working but this wasn’t the right solution..

    On this bug report i found out i had the same problem and the same symptoms: i had disabled ipv6 support, and this is what broke the forwarding!

    The solution is to add:

    AddressFamily inet

    in sshd_config! (or enable ipv6 again ;))

  • Apache PROXYPASS, NEGATIVE PROXYPASS AND AUTH_BASIC

    Today i had to face a weird problem with Apache 2. I wanted to setup a webmail on the SAME virtualhost that i was using to proxy to another host.
    Here’s a summary of my configuration:

    <VirtualHost *:80>

    ServerAdmin sysadmin@localhost

    DocumentRoot /var/www/folder

    ServerName localhost

    Alias /mail /var/lib/roundcube/
    <Directory /var/lib/roundcube/>

    Options Indexes Includes FollowSymLinks

    AllowOverride All

    AuthType Basic

    AuthUserFile /var/lib/roundcube/.htpasswd

    AuthName “Protected Folder”

    require valid-user

    </Directory>
    ProxyRequests Off

    ProxyPreserveHost On
    <Proxy *>

    Order deny,allow

    Allow from all

    </Proxy>
    ProxyPass /mail/ !

    ProxyPass / http://0.0.0.0/ ttl=60 retry=0 status=I keepalive=on timeout=2500 disablereuse=on
    </VirtualHost>

    The problem is that the auth_basic wasn’t working correctly in this setup, Apache was answering with a 200 instead of a 401 message, which prevented the browser from understanding it was actually an authentication..

    But this config was working fine without the auth, the webmail was working. And it was working fine with auth but no proxypass.
    So what was wrong?! Thanks to the guys @freenode i discovered that Apache was proxying the requests to custom errors in /error/ (as i uncommented the custom errors in apache2.conf). The solution was to add:

    ProxyPass /error/ !

    Turn loglevel to debug in case you have a similar issue, in my case i could read this:

    [Fri Mar 04 15:44:36 2011] [debug] mod_proxy_http.c(56): proxy: HTTP: canonicalising URL //10.10.10.10/error/HTTP_UNAUTHORIZED.html.var
    [Fri Mar 04 15:44:36 2011] [debug] proxy_util.c(1506): [client 1.1.1.1] proxy: http: found worker http://10.10.10.10/ for http://10.10.10.10/error/HTTP_UNAUTHORIZED.html.var

    Hope it helps.

  • ffmpeg-php – error: ‘PIX_FMT_RGBA32’ undeclared (first use in this function)

    /tmp/ffmpeg-php-0.6.0/ffmpeg_frame.c: In function ‘zim_ffmpeg_frame_toGDImage’:
    /tmp/ffmpeg-php-0.6.0/ffmpeg_frame.c:336: error: ‘PIX_FMT_RGBA32’ undeclared (first use in this function)
    /tmp/ffmpeg-php-0.6.0/ffmpeg_frame.c:336: error: (Each undeclared identifier is reported only once
    /tmp/ffmpeg-php-0.6.0/ffmpeg_frame.c:336: error: for each function it appears in.)
    /tmp/ffmpeg-php-0.6.0/ffmpeg_frame.c: In function ‘zim_ffmpeg_frame_ffmpeg_frame’:
    /tmp/ffmpeg-php-0.6.0/ffmpeg_frame.c:421: error: ‘PIX_FMT_RGBA32’ undeclared (first use in this function)
    make: *** [ffmpeg_frame.lo] Erreur 1

    To fix this, replace PIX_FMT_RGBA32 with PIX_FMT_RGB32 . You can use “rpl” to replace files recursively:

    cd to the ffmpeg folder and run this command (beware!):

    rpl -R PIX_FMT_RGBA32 PIX_FMT_RGB32 *

  • Compiling Micropolis (Simcity) on Ubuntu Intrepid (8.10) and Jaunty (9.04)

    Update: Starting from Ubuntu Karmic (9.10), Micropolis is in your apt!

    You need the following:

    sudo apt-get install libx11-dev libxpm-dev x11proto-xext-dev libxext-dev

    You also need yacc, it will fail if you use bison or btyacc:

    btyaccpa.ske:111: erreur: expected specifier-qualifier-list before ‘yyparsestate’
    btyaccpa.ske:128: erreur: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
    btyaccpa.ske:131: erreur: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
    btyaccpa.ske:180: erreur: expected ‘)’ before ‘*’ token
    btyaccpa.ske:181: erreur: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘*’ token
    btyaccpa.ske:182: erreur: expected ‘)’ before ‘*’ token
    btyaccpa.ske: In function ‘yyparse’:
    btyaccpa.ske:193: erreur: ‘yyparsestate’ undeclared (first use in this function)
    btyaccpa.ske:193: erreur: (Each undeclared identifier is reported only once
    btyaccpa.ske:193: erreur: for each function it appears in.)
    btyaccpa.ske:193: erreur: ‘yyerrctx’ undeclared (first use in this function)
    btyaccpa.ske:206: erreur: ‘yyps’ undeclared (first use in this function)
    btyaccpa.ske:257: erreur: ‘yypath’ undeclared (first use in this function)

    Or:

    tclxgdat.y:67.15: syntax error, unexpected =
    tclxgdat.y:79.16: syntax error, unexpected =
    tclxgdat.y:83.25: syntax error, unexpected =
    tclxgdat.y:86.32-33: valeur $ invalide : $3

    But works with byacc:

    sudo apt-get install byacc

    Get the micropolis source (micropolis-activity-source.tgz) from http://www.donhopkins.com/home/micropolis/ , extract it:

    tar -zxvf micropolis-activity-source.tgz

    cd micropolis-activity/

    Then apply this patch and compile:

    wget http://rmdir.de/~michael/micropolis_git.patch

    patch -p1 < micropolis_git.patch

    cd src

    make clean (if you tried compiling with another yacc before)

    make install

    If you get the following error then when doing ./Micropolis:

    sh: Syntax error: Bad fd number
    sh: Syntax error: Bad fd number

    Do:

    sudo apt-get install rpl

    go inside the micropolis-activity folder and run:

    rpl -R “/bin/sh” “/bin/bash” *

    And recompile Micropolis:

    cd src

    make clean install

    Enjoy Micropolis! 🙂

  • Best Linux graphical editor for large files

    You might need a graphical editor to edit large dump files. Most of the graphical editors on linux cannot handle large files, so check out nedit, using it i was able to edit a 17mb file without delay.