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

502 Bad Gateway after update from v0.6.0 to v0.7.0 #1400

Open
SegaSh99 opened this issue Oct 25, 2024 · 26 comments
Open

502 Bad Gateway after update from v0.6.0 to v0.7.0 #1400

SegaSh99 opened this issue Oct 25, 2024 · 26 comments

Comments

@SegaSh99
Copy link

I use docker and set up docker compose config with Marzban and Traefik Proxy. On Marzban version 0.6.0 everything works, but after upgrading to version 0.7.0 I get an error
I also used Nginx, which also returns an error
When trying to open the image URL directly (http://172.18.0.4:8000/), I got HTTP ERROR 502

Machine details (please complete the following information):

  • OS: Ubuntu 22.04
  • Docker Compose version v2.27.0
@ImMohammad20000
Copy link
Collaborator

hi send marzban logs

@atomexpert
Copy link

I use docker and set up docker compose config with Marzban and Traefik Proxy. On Marzban version 0.6.0 everything works, but after upgrading to version 0.7.0 I get an error I also used Nginx, which also returns an error When trying to open the image URL directly (http://172.18.0.4:8000/), I got HTTP ERROR 502

Machine details (please complete the following information):

  • OS: Ubuntu 22.04
  • Docker Compose version v2.27.0

Same problem. After installation the panel does not work

@SerGioPicconti
Copy link

People are you reading logs sometimes?

Since 0.7 release you need HTTPS (SSL) connection to panel to open it. It won't work anymore without secure connection. With https everything works great, including nginx.
Buy some domain, use certbot and enjoy)

@PrevikYT
Copy link

so, how can i downgrade my panel

@SegaSh99
Copy link
Author

People are you reading logs sometimes?

Since 0.7 release you need HTTPS (SSL) connection to panel to open it. It won't work anymore without secure connection. With https everything works great, including nginx. Buy some domain, use certbot and enjoy)

image

nginx-1 | 2024/10/27 11:18:28 [error] 29#29: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.3, server: , request: "GET /dashboard HTTP/1.1", upstream: "http://172.19.0.2:8000/dashboard", host: "marzban.vpn.my-domain.ru"

@SerGioPicconti
Copy link

SerGioPicconti commented Oct 27, 2024

People are you reading logs sometimes?
Since 0.7 release you need HTTPS (SSL) connection to panel to open it. It won't work anymore without secure connection. With https everything works great, including nginx. Buy some domain, use certbot and enjoy)

image

nginx-1 | 2024/10/27 11:18:28 [error] 29#29: *1 connect() failed (111: Connection refused) while connecting to upstream, client: 172.19.0.3, server: , request: "GET /dashboard HTTP/1.1", upstream: "http://172.19.0.2:8000/dashboard", host: "marzban.vpn.my-domain.ru"

Provide nginx & marzban .env
Looks like nginx config mismatch marzban port or ip or something else

@SerGioPicconti
Copy link

so, how can i downgrade my panel

You can install specific release if you want
bash -c "$(curl -sL https://github.com/Gozargah/Marzban-scripts/raw/master/marzban.sh)" @ install v0.6.0

@SegaSh99
Copy link
Author

SegaSh99 commented Oct 27, 2024

Provide nginx & marzban .env

nginx:

server {
    listen 80;
    listen [::]:80;

    location / {
        proxy_pass http://marzban:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-SSL on;
    }
}

.env: The rest of the variables are default (not changed)

# Main
# ----
PROJECT_NAME=marzban
DOMAIN=vpn.my-domain.ru

# Docker
# ------
COMPOSE_FILE=docker-compose.yml
DOCKER_MYSQL_PORT=12222

# MySQL
# ---------
MYSQL_DATABASE=marzban
MYSQL_USER=vpn
MYSQL_PASSWORD=vpn
MYSQL_ROOT_PASSWORD=vpn


# Web server configuration
UVICORN_HOST=0.0.0.0
UVICORN_PORT=8000

## We highly recommend add admin using `marzban cli` tool and do not use
## the following variables which is somehow hard codded infrmation.
SUDO_USERNAME="login"
SUDO_PASSWORD="pass"

docker compose:

services:
  traefik:
    image: traefik:3
    restart: on-failure
    volumes:
      - /etc/localtime:/etc/localtime:ro
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/data/traefik.yml:/traefik.yml:ro
      - ./traefik/data/acme.json:/acme.json
      - ./traefik/configurations:/configurations:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.${PROJECT_NAME}-traefik.rule=Host(`traefik.${DOMAIN}`)"
      - "traefik.http.routers.${PROJECT_NAME}-traefik.service=api@internal"
      - "traefik.http.routers.${PROJECT_NAME}-traefik.middlewares=user-auth@file"
      - "traefik.http.routers.${PROJECT_NAME}-traefik.tls=true"
      - "traefik.http.routers.${PROJECT_NAME}-traefik.tls.certresolver=letsEncrypt"
    networks:
      - vpn
    ports:
      - "80:80"
      - "443:443"

  nginx:
    image: nginx:1.27-alpine
    restart: on-failure
    volumes:
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.${PROJECT_NAME}-nginx.rule=Host(`marzban.${DOMAIN}`)"
      - "traefik.http.routers.${PROJECT_NAME}-nginx.tls=true"
      - "traefik.http.routers.${PROJECT_NAME}-nginx.tls.certresolver=letsEncrypt"
    depends_on:
      - traefik
    networks:
      - vpn

  marzban:
    image: gozargah/marzban:latest
    restart: on-failure
    env_file: .env
    volumes:
      - /var/lib/marzban:/var/lib/marzban
    networks:
      - vpn

networks:
  vpn:
    driver: bridge

I added Nginx as an experiment, but you can directly direct traffic to the marzban container
Both options do not work on version 0.7.0
https://traefik.vpn.my-domain.ru - is work
https://marzban.vpn.my-domain.ru - 502 Bad Gateway

@SerGioPicconti
Copy link

server {
    listen **80**;
    listen [::]:**80**;

    location / {
        proxy_pass **http://marzban:8000**;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Forwarded-SSL on;
    }
}

First of all, port 80 is for plain http, NOT HTTPS!
Second - where did you get http://marzban host? Why? What for?
It's just simple like http://127.0.0.1:8000

@SerGioPicconti
Copy link

And you don't need this DOMAIN=vpn.my-domain.ru if you use NGINX ssl config!
And I hope you are not really using my-domain.ru because it's from some example and not for real use

@SegaSh99
Copy link
Author

First of all, port 80 is for plain http, NOT HTTPS!
Second - where did you get http://marzban host? Why? What for?
It's just simple like http://127.0.0.1:8000

http://marzban - This is the name of the container that needs to be proxy the request.
Nginx is inside the container, so it works with port 80
Port 443 accepts traefik and forwards it to the container

@SegaSh99
Copy link
Author

And you don't need this DOMAIN=vpn.my-domain.ru if you use NGINX ssl config! And I hope you are not really using my-domain.ru because it's from some example and not for real use

SSL is set by traefik, not nginx

@SegaSh99
Copy link
Author

I downgraded to 0.6.0 and everything worked
So don't write that my config is not working if you don't understand it

image

@SerGioPicconti
Copy link

SerGioPicconti commented Oct 27, 2024

First of all, port 80 is for plain http, NOT HTTPS!
Second - where did you get http://marzban host? Why? What for?
It's just simple like http://127.0.0.1:8000

http://marzban - This is the name of the container that needs to be proxy the request. Nginx is inside the container, so it works You wrote that you've tried nginx and it's also didn't worked!

As I can see you proxies port 443 to traefik, which must provide SSL connection from user to marzban host. If you have troubles with traefik - you must config it to redirect from port 80 to port 443 and proxy from port 443 to localhost:8000.
For now it looks like you have wrong config and adding nginx config as you have priveded won't help you because it even doesn't have valid https proxy config!
You have to down traefik container, set nginx config as it should be for https, and then it will work through nginx.
Unfortunately what is traefik and how to config it (and, i'm really don't understant what is this for in your case) I don't know

@SerGioPicconti
Copy link

I downgraded to 0.6.0 and everything worked So don't write that my config is not working if you don't understand it

image

Это ты немного не понимаешь!
У тебя не настроен нормальный конфиг через HTTPS, а начиная с 0.7 релиза без HTTPS марзбан больше не пашет!
Поэтому у тебя и работает 0.6 релиз

Разберись в своей каше конфигов, настрой нормально nginx с использованием https и ssl и все спокойно заработает.
Ты можешь зайти в ветку в телеге и посмотреть что все нормально поднимают https конфиги и юзают. Ты же зачем то навертел и траефик и nginx и еще и не настроил нормально. У тебя nginx кроме трафика НЕ https ничего не видит и не проксит - как он по твоему должен заработать??

@SerGioPicconti
Copy link

И разберись как работает проксирование на контейнеры... указание на http://marzban - с таким же успехом можешь по-русски написать - ничего как не работало так и не заработает!

@SegaSh99
Copy link
Author

Мне нужна комбинация traefik + marzban, без всяких nginx и прочего

@M03ED
Copy link
Collaborator

M03ED commented Oct 27, 2024

add this to your marzban docker file

    ports:
      - "127.0.0.1:3333:3333"

change port to your dashboard port

@M03ED
Copy link
Collaborator

M03ED commented Oct 27, 2024

and use 127.0.0.1 instead on 172.*

@SerGioPicconti
Copy link

Мне нужна комбинация traefik + marzban, без всяких nginx и прочего

Значит нужно настроить верно проксификацию 443 порта в траефике. 80 порт тут не нужен вообще

@yaramahmadi
Copy link

    ports:
      - "127.0.0.1:3333:3333"

I tried this solution, but it didn’t work for me.

Thank you.

@M03ED
Copy link
Collaborator

M03ED commented Oct 28, 2024

map this file to your docker
something like this:
then you should be able to use 172 range as uvicorn host
if this worked i will merge it

volumes:
  - /var/lib/marzban:/var/lib/marzban   
  - /opt/marzban/main.py:/code/main.py
import click
import logging
import os
import ssl
import ipaddress

import uvicorn
from cryptography import x509
from cryptography.hazmat.backends import default_backend

from app import app, logger
from config import (DEBUG, UVICORN_HOST, UVICORN_PORT, UVICORN_SSL_CERTFILE,
                    UVICORN_SSL_KEYFILE, UVICORN_UDS)


def check_and_modify_ip(ip_address: str) -> str:
    """
    Check if an IP address is private. If not, return localhost.

    IPv4 Private range = [
        "192.168.0.0",
        "192.168.255.255",
        "10.0.0.0",
        "10.255.255.255",
        "172.16.0.0",
        "172.31.255.255"
    ]

    Args:
        ip_address (str): IP address to check

    Returns:
        str: Original IP if private, otherwise localhost

    Raises:
        ValueError: If the provided IP address is invalid, return localhost.
    """
    try:
        # Convert string to IP address object
        ip = ipaddress.ip_address(ip_address)

        if ip.is_private:
            return ip_address
        else:
            return "localhost"

    except ValueError as e:
        return "localhost"


def validate_cert_and_key(cert_file_path, key_file_path):
    if not os.path.isfile(cert_file_path):
        raise ValueError(
            f"SSL certificate file '{cert_file_path}' does not exist.")
    if not os.path.isfile(key_file_path):
        raise ValueError(f"SSL key file '{key_file_path}' does not exist.")

    try:
        context = ssl.create_default_context()
        context.load_cert_chain(certfile=cert_file_path, keyfile=key_file_path)
    except ssl.SSLError as e:
        raise ValueError(f"SSL Error: {e}")

    try:
        with open(cert_file_path, 'rb') as cert_file:
            cert_data = cert_file.read()
            cert = x509.load_pem_x509_certificate(cert_data, default_backend())

        if cert.issuer == cert.subject:
            raise ValueError(
                "The certificate is self-signed and not issued by a trusted CA.")

    except Exception as e:
        raise ValueError(f"Certificate verification failed: {e}")


if __name__ == "__main__":
    # Do NOT change workers count for now
    # multi-workers support isn't implemented yet for APScheduler and XRay module

    bind_args = {}

    if UVICORN_SSL_CERTFILE and UVICORN_SSL_KEYFILE:
        validate_cert_and_key(UVICORN_SSL_CERTFILE, UVICORN_SSL_KEYFILE)

        bind_args['ssl_certfile'] = UVICORN_SSL_CERTFILE
        bind_args['ssl_keyfile'] = UVICORN_SSL_KEYFILE

        if UVICORN_UDS:
            bind_args['uds'] = UVICORN_UDS
        else:
            bind_args['host'] = UVICORN_HOST
            bind_args['port'] = UVICORN_PORT

    else:
        if UVICORN_UDS:
            bind_args['uds'] = UVICORN_UDS
        else:

            ip = check_and_modify_ip(UVICORN_HOST)

            logger.warning(f"""
{click.style('IMPORTANT!', blink=True, bold=True, fg="yellow")}
You're running Marzban without specifying {click.style('UVICORN_SSL_CERTFILE', italic=True, fg="magenta")} and {click.style('UVICORN_SSL_KEYFILE', italic=True, fg="magenta")}.
The application will only be accessible through localhost. This means that {click.style('Marzban and subscription URLs will not be accessible externally', bold=True)}.

If you need external access, please provide the SSL files to allow the server to bind to 0.0.0.0. Alternatively, you can run the server on localhost or a Unix socket and use a reverse proxy, such as Nginx or Caddy, to handle SSL termination and provide external access.

If you wish to continue without SSL, you can use SSH port forwarding to access the application from your machine. note that in this case, subscription functionality will not work. 

Use the following command:

{click.style(f'ssh -L {UVICORN_PORT}:localhost:{UVICORN_PORT} user@server', italic=True, fg="cyan")}

Then, navigate to {click.style(f'http://{ip}:{UVICORN_PORT}', bold=True)} on your computer.
            """)

            bind_args['host'] = ip
            bind_args['port'] = UVICORN_PORT

    if DEBUG:
        bind_args['uds'] = None
        bind_args['host'] = '0.0.0.0'

    try:
        uvicorn.run(
            "main:app",
            **bind_args,
            workers=1,
            reload=DEBUG,
            log_level=logging.DEBUG if DEBUG else logging.INFO
        )
    except FileNotFoundError:  # to prevent error on removing unix sock
        pass

@M03ED
Copy link
Collaborator

M03ED commented Oct 29, 2024

if nobody want to test this i can close issue

@yaramahmadi
Copy link

if nobody want to test this i can close issue

I'll test it and let you know within the next hour.

@yaramahmadi
Copy link

if nobody want to test this i can close issue

I'll test it and let you know within the next hour.

I used methods 1 and 3, and the issue has been resolved. Thank you!


1. Using Reverse Proxy in Nginx (with HTTPS)

To access the application via HTTPS in Nginx, add the following configuration to your Nginx configuration file:

server {
    listen 80;
    server_name test.domain.com;

    # Redirect HTTP to HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

server {
    listen 443 ssl;
    server_name test.domain.com;

    ssl_certificate /path/to/fullchain.pem;
    ssl_certificate_key /path/to/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}
  1. Replace fullchain.pem and privkey.pem with the paths to your SSL certificates.

  2. Then restart Nginx:

    sudo systemctl restart nginx

Now, HTTP requests will be redirected to https://test.domain.com/dashboard and proxied to port 8000.

2. Using an SSH Tunnel

This method doesn’t require any changes to support HTTPS, and you can temporarily access port 8000 through the tunnel:

ssh -L 8000:localhost:8000 user@server_ip

3. Configuration in Nginx Proxy Manager (with HTTPS)

To add HTTPS in Nginx Proxy Manager:

  1. Log in to Nginx Proxy Manager: Open the panel and navigate to Proxy Hosts. Click on Add Proxy Host.

  2. Initial Settings:

    • Under Domain Names, enter test.domain.com.
    • Set Scheme to http.
    • Set Forward Hostname / IP to 127.0.0.1 and Forward Port to 8000.
  3. Enable SSL:

    • Go to the SSL tab.
    • Enable Enable SSL.
    • Select Force SSL to redirect all HTTP traffic to HTTPS.
    • If using Let’s Encrypt, enable Request a new SSL Certificate and enter the required information to obtain a certificate.
  4. Advanced Settings:

    • Go to the Advanced tab and add the following headers in Custom Nginx Configuration:

      proxy_set_header Host $host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
  5. Save Settings: After saving, you can access the application via https://test.domain.com/dashboard.

@M03ED
Copy link
Collaborator

M03ED commented Oct 29, 2024

im happy your problem solved
@SegaSh99 what about you ?

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

No branches or pull requests

7 participants