Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Submission: Zoraxy - Reverse Proxy Manager #1751

Open
wants to merge 32 commits into
base: master
Choose a base branch
from

Conversation

dennysubke
Copy link
Contributor

App Submission

Zoraxy - Reverse Proxy Manager

...

Icon

logo

...

Gallery images

1

2

3

4

5

...

I have tested my app on:

  • umbrelOS on a Raspberry Pi
  • umbrelOS on an Umbrel Home
  • umbrelOS on Linux VM

@dennysubke
Copy link
Contributor Author

Zoraxy is a lightweight alternative to Nginx, ideal for home servers like Umbrel, offering easy setup through a graphical interface. With built-in authentication and automatic SSL handling, it’s simple and resource-efficient.

Despite its user-friendliness, it remains more powerful than Nginx in self-hosted environments.

@nmfretz
Copy link
Contributor

nmfretz commented Nov 8, 2024

Thanks for yet ANOTHER submission @dennysubke!

I don't have familiarity with Zoraxy, but do you know if this bind mount is needed:

- /var/run/docker.sock:/var/run/docker.sock

Binding the host's docker socket is, unfortunately, a deal-breaker for security reasons. This would give Zoraxy complete access to the Docker daemon on the host, allowing it to manage other containers and easily break out of the containerized environment. With access to /var/run/docker.sock, the container gains root-level control over the host. Any process in the container could start privileged containers, access sensitive files, or even compromise the entire host system

There's a couple apps in our app store that get around this by running alongside a docker-in-docker (dind) container and binding to the dind's docker socket as a workaround (e.g., portainer and dockge).

@dirstel
Copy link
Contributor

dirstel commented Nov 11, 2024

docker.sock is "Used for additional functionality with Zoraxy." Link
Maybe an app like zoraxy should be part of Umbrel itself? Thinking about hooks/configs to define a subdomain used by apps...

@dennysubke
Copy link
Contributor Author

Thanks for yet ANOTHER submission @dennysubke!

I don't have familiarity with Zoraxy, but do you know if this bind mount is needed:

- /var/run/docker.sock:/var/run/docker.sock

Binding the host's docker socket is, unfortunately, a deal-breaker for security reasons. This would give Zoraxy complete access to the Docker daemon on the host, allowing it to manage other containers and easily break out of the containerized environment. With access to /var/run/docker.sock, the container gains root-level control over the host. Any process in the container could start privileged containers, access sensitive files, or even compromise the entire host system

There's a couple apps in our app store that get around this by running alongside a docker-in-docker (dind) container and binding to the dind's docker socket as a workaround (e.g., portainer and dockge).

Good point - binding /var/run/docker.sock indeed poses security risks. Could you make the changes to use docker-in-docker (dind) instead?

@nmfretz
Copy link
Contributor

nmfretz commented Nov 21, 2024

Maybe an app like zoraxy should be part of Umbrel itself? Thinking about hooks/configs to define a subdomain used by apps...

Thanks for the suggestion @dirstel. When we get a feature like this added (on the roadmap) we'll likely use something lower-level. We've got some ideas 😉

Copy link
Contributor

@nmfretz nmfretz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apologies for the delay @dennysubke! Thanks again for yet another submission 🫡.

Good point - binding /var/run/docker.sock indeed poses security risks. Could you make the changes to use docker-in-docker (dind) instead?

Ah, sorry I hadn't really looked at the app at all when I made that comment. Now that I see what this is we can't use dind here because Zoraxy is binding to the Docker socket to get info on what Docker containers are running on the host. If we bind the socket of a dind container it would be useless because no containers will be running in it.

I just took a quick look through the codebase and I think there's a path forward for us here:

  • the docker socket is being used for some quality of life improvements when running zoraxy via Docker. For example, when creating proxy rules it allows you to select from a list of running containers to get IP addresses, ports, etc.
  • that makes things nice, but it isn't strictly required for zoraxy to run
  • we can remove the socket bind and also add DOCKER: "false" as an env var which I think will make it so the components in the UI that show running docker containers won't show up so users don't think something is broken.

I've gone through and left a review below. Let me know if anything is confusing.

@@ -0,0 +1,23 @@
services:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current Compose doesn't use version in the docker-compose.yml, but we need to add version: '3.7' here anyways to maintain compatibility with umbrelOS 0.5. Similar to #1742 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Added version: '3.7' to ensure compatibility with UmbrelOS 0.5. 😊

environment:
APP_HOST: zoraxy_server_1
APP_PORT: 8000
PROXY_AUTH_ADD: "false"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that there is a NOAUTH environment variable we can use to disable authentication for the Zoraxy UI:
https://github.com/tobychui/zoraxy/tree/main/docker#environment

What do you think about removing Zoraxy's auth and then removing PROXY_AUTH_ADD: "false" here so that the UI is protected by umbrelOS's auth and inherits other security features like 2FA if a user has it enabled? This also means reduced friction for a user signing in since they can:

  • log in through umbrel homescreen.
  • click Zoraxy and not have to input credentials again.

Similar to what we did here: #1742 (comment)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great, already taken care of!

Comment on lines 10 to 13
#ports: -> The proxy service is listening on port 8400
# 8480:80
# 8443:443
# 8400:8000
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since Zoraxy is a reverse proxy doesn't it need to expose http and https ports for its basic functionality?

User's are going to need to open ports on their router and then port forward to Zoraxy running on their Umbrel. You can bind to free ports that haven't been taken by other apps yet. So something like:

ports:
  - 41080:80
  - 41443:443

Then right at the top of the app description you could note which ports are for which protocol.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Ports 41080 for HTTP and 41443 for HTTPS are now set, and I'll add the protocol details to the app description.

# 8443:443
# 8400:8000
volumes:
- ${APP_DATA_DIR}/config/:/opt/zoraxy/config/
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's do the same thing as the other submissions and put this one level deeper on the host inside a parent data directory so that it has similar structure to the majority of other apps, and it makes it easy to add more bind mounts inside data in the future.

- ${APP_DATA_DIR}/data/config/:/opt/zoraxy/config/

Reminder, you'll need to make the equivalent change to the committed directories.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Moved it one level deeper inside a parent data directory.

volumes:
- ${APP_DATA_DIR}/config/:/opt/zoraxy/config/
# ${APP_DATA_DIR}/zerotier/config/:/var/lib/zerotier-one/ -> If you are not using ZeroTier, this directory is irrelevant.
- /var/run/docker.sock:/var/run/docker.sock
Copy link
Contributor

@nmfretz nmfretz Nov 21, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove the docker socket bind based on the discussion above: #1751 (review)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done! Removed the Docker socket bind as discussed.

Comment on lines 8 to 9
description: >-
Zoraxy is a powerful, user-friendly reverse proxy server and forwarding tool, designed to provide a straightforward, flexible, and secure method for managing web traffic within home labs and developer environments. Written in Go, Zoraxy caters to both novice and experienced users by simplifying the process of routing HTTP requests to backend servers, enabling efficient and reliable service management without relying on traditional, more complex servers like NGINX or Apache.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we should add port instructions and a warning at the top here, what do you think? You can just steal it directly from the nginx proxy manager app:

description: >-
Expose your apps to the internet easily and securely.
⚠️ Be cautious when exposing apps to the public internet. Ensure they have proper security, such as login protection, and avoid exposing sensitive apps without adequate safeguards.
🔧 Nginx Proxy Manager uses port 40080 for HTTP (unsecured) traffic and port 40443 for HTTPS (secured) traffic.
To make your apps accessible from the public internet, you will need to set up port forwarding on your router.
Forward external port 80 (HTTP) to internal port 40080 and external port 443 (HTTPS) to internal port 40443.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💪 Added port instructions and a warning at the top, following the nginx proxy manager app format.

Comment on lines +44 to +47
gallery:
- 1.jpg
- 2.jpg
- 3.jpg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You've got 5 lovely gallery images, so gotta add 4 and 5 😉

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! 😃 Added gallery images 4 and 5 to complete the set. 👌

Copy link

⚠️   Linting finished with 1 warning   ⚠️

Thank you for your submission! This is an automated linter that checks for common issues in pull requests to the Umbrel App Store.

Please review the linting results below and make any necessary changes to your submission.

Linting Results

Severity File Description
ℹ️ zoraxy/docker-compose.yml Mounted file/directory "/zoraxy/data/config/" doesn't exist:
The volume "${APP_DATA_DIR}/data/config/:/opt/zoraxy/config" tries to mount the file/directory "/zoraxy/data/config/", but it is not present. This can lead to permission errors!
ℹ️ zoraxy/docker-compose.yml External port mapping "41080:80":
Port mappings may be unnecessary for the app to function correctly. Docker's internal DNS resolves container names to IP addresses within the same network. External access to the web interface is handled by the app_proxy container. Port mappings are only needed if external access is required to a port not proxied by the app_proxy, or if an app needs to expose multiple ports for its functionality (e.g., DHCP, DNS, P2P, etc.).
ℹ️ zoraxy/docker-compose.yml External port mapping "41443:443":
Port mappings may be unnecessary for the app to function correctly. Docker's internal DNS resolves container names to IP addresses within the same network. External access to the web interface is handled by the app_proxy container. Port mappings are only needed if external access is required to a port not proxied by the app_proxy, or if an app needs to expose multiple ports for its functionality (e.g., DHCP, DNS, P2P, etc.).
ℹ️ zoraxy/docker-compose.yml Potentially using unsafe user in service "server":
The default container user "root" can lead to security vulnerabilities. If you are using the root user, please try to specify a different user (e.g. "1000:1000") in the compose file or try to set the UID/PUID and GID/PGID environment variables to 1000.
⚠️ zoraxy/umbrel-app.yml "icon" and "gallery" needs to be empty for new app submissions:
The "icon" and "gallery" fields must be empty for new app submissions as it is being created by the Umbrel team.

Legend

Symbol Description
Error: This must be resolved before this PR can be merged.
⚠️ Warning: This is highly encouraged to be resolved, but is not strictly mandatory.
ℹ️ Info: This is just for your information.

@dennysubke
Copy link
Contributor Author

Thanks for yet ANOTHER submission @dennysubke!

I don't have familiarity with Zoraxy, but do you know if this bind mount is needed:

- /var/run/docker.sock:/var/run/docker.sock

Binding the host's docker socket is, unfortunately, a deal-breaker for security reasons. This would give Zoraxy complete access to the Docker daemon on the host, allowing it to manage other containers and easily break out of the containerized environment. With access to /var/run/docker.sock, the container gains root-level control over the host. Any process in the container could start privileged containers, access sensitive files, or even compromise the entire host system

There's a couple apps in our app store that get around this by running alongside a docker-in-docker (dind) container and binding to the dind's docker socket as a workaround (e.g., portainer and dockge).

Hey @nmfretz I’ve made the necessary adjustments. Hope I didn’t miss any points. Thank you for your detailed explanations. These will help me for future projects. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants