**Purpose**: Sometimes you just want an instance of Firefox running on an Alpine Linux container, that has persistence (Extensions, bookmarks, history, etc) outside of the container (with bind-mapped folders). This is useful for a number of reasons, but insecure by default, so you have to protect it behind something like a [Keycloak Server](https://docs.bunny-lab.io/Docker%20%2526%20Kubernetes/Docker/Docker%20Compose/Keycloak/) so it is not misused. ## Keycloak Authentication Sequence ``` mermaid sequenceDiagram participant User participant Traefik as Traefik Reverse Proxy participant Keycloak participant RockyLinux as Rocky Linux VM participant FirewallD as FirewallD participant Alpine as Alpine Container User->>Traefik: Access https://work-environment.bunny-lab.io Traefik->>Keycloak: Redirect to Authenticate against Work Realm User->>Keycloak: Authenticate Keycloak->>User: Authorization Cookie Stored on Internet Browser User->>Traefik: Pass Authorization Cookie to Traefik Traefik->>RockyLinux: Traefik Forwards Traffic to Rocky Linux VM RockyLinux->>FirewallD: Traffic Passes Local Firewall FirewallD->>RockyLinux: Filter traffic (Port 5800) FirewallD->>Alpine: Allow Traffic from Traefik Alpine->>User: WebUI Access to Firefox Work Environment Granted ``` ## Docker Configuration ```yaml title="docker-compose.yml" version: '3' services: firefox: image: jlesage/firefox # Docker image for Firefox environment: - TZ=America/Denver # Timezone setting - DARK_MODE=1 # Enable dark mode - WEB_AUDIO=1 # Enable web audio - KEEP_APP_RUNNING=1 # Keep the application running ports: - "5800:5800" # Port mapping for VNC WebUI volumes: - /srv/containers/firefox:/config:rw # Persistent storage for configuration restart: always # Always restart the container in case of failure network_mode: host # Use the host network ``` ```yaml title=".env" N/A ``` ## Local Firewall Hardening It is important, due to how this browser just allows anyone to access it, to lock it down to only allow access to the SSH port and port 5800 to specifically-allowed devices, in this case, the Traefik Reverse Proxy. This ensures that it only allows the proxy to communicate with Firefox's container, keeping it securely protected behind Keycloak's middware in Traefik. These rules will drop all traffic by default, allow port 22, and restrict access to port 5800. ``` sh # Set the default zone to drop sudo firewall-cmd --set-default-zone=drop # Create a new zone named custom-trusted sudo firewall-cmd --permanent --new-zone=traefik-proxy # Allow traffic to port 5800 only from 192.168.5.29 in the traefik-proxy zone sudo firewall-cmd --permanent --zone=traefik-proxy --add-source=192.168.5.29 sudo firewall-cmd --permanent --zone=traefik-proxy --add-port=5800/tcp # Allow SSH traffic on port 22 from any IP in the drop zone sudo firewall-cmd --permanent --zone=drop --add-service=ssh # Reload FirewallD to apply the changes sudo firewall-cmd --reload ``` ## Traefik Reverse Proxy Configuration If the container does not run on the same host as Traefik, you will need to manually add configuration to Traefik's dynamic config file, outlined below. ```yaml http: routers: work-environment: entryPoints: - websecure tls: certResolver: letsencrypt service: work-environment rule: Host(`work-environment.bunny-lab.io`) middlewares: - work-environment # Referencing the Keycloak Server services: work-environment: loadBalancer: servers: - url: http://192.168.5.4:5800 passHostHeader: true # # Adding forwardingTimeouts to set the send and read timeouts to 1 hour (3600 seconds) # forwardingTimeouts: # dialTimeout: "3600s" # responseHeaderTimeout: "3600s" ``` ## Firefox Special Configurations Due to the nature of how this is deployed, you need to make some additional configurations to the Firefox settings after-the-fact. Some of this could be automated with environment variables at deployment time, but for now will be handled manually. - **Install Power Tabs Extension**: This extension is useful for keeping things organized. - **Install Merge All Windows Extension**: At times, you may misclick somewhere in the Firefox environment causing Firefox to open a new instance / window losing all of your tabs, and because there is no window manager, there is no way to alt+tab or switch between the instances of Firefox, effectively breaking your current session forcing you to re-open tabs. With this extension, you can merge all of the windows, collapsing them into one window, resolving the issue. - **Configure New Tab behavior**: If a new tab opens in a new window, it will absolutely throw everything into disarray, that is why all hyperlinks will be forced to open in a new tab instead of a new window. You can do this by navigating to `about:config` and setting the variable `browser.link.open_newwindow.restriction` to a value of `0`. [Original Reference Documentation](https://support.mozilla.org/en-US/questions/1066799)