Skip to content

Commit

Permalink
Dev to main - 21102024 (#9)
Browse files Browse the repository at this point in the history
* Added custom template for subscription
* Fixed warp install, add dpkg form
* Fix custom SSH port configuration
* Bump CI versions
* Decardcode image names and tags
* Set grant type to API calls
  • Loading branch information
v-kamerdinerov authored Oct 28, 2024
1 parent c02ec32 commit c921411
Show file tree
Hide file tree
Showing 15 changed files with 748 additions and 156 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/linter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,12 @@ jobs:
runs-on: ubuntu-20.04
steps:
- name: Check out the codebase.
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
path: 'v-kamerdinerov.marzban-haproxy-ansible'

- name: Set up Python 3.
uses: actions/setup-python@v2
uses: actions/setup-python@v5
with:
python-version: '3.x'

Expand Down
2 changes: 1 addition & 1 deletion group_vars/marzban/marzban.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ marzban_domain: example-domain.com
marzban_panel_uri: "panel.{{ marzban_domain }}"

# SNI for traffic masking
marzban_sni: "discord.com"
marzban_sni: "awesome.sni"

# Login credentials for panel access
marzban_panel_login: "admin"
Expand Down
3 changes: 3 additions & 0 deletions roles/common/tasks/cert.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@
when: item.key.endswith('.cert')
register: _ca_certificates_copied
notify: Update ca-certificates

- name: Flush handlers
meta: flush_handlers
9 changes: 3 additions & 6 deletions roles/common/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
---
- name: SSH
include_tasks: ssh_port.yml
tags: ssh
- name: Common
include_tasks: common.yml
tags: common
# loop: "{{ groups['marzban'] }}"
# loop_control:
# loop_var: host
- name: Limits
include_tasks: limits.yml
tags: limits
Expand All @@ -14,9 +14,6 @@
- name: Certificate
include_tasks: cert.yml
tags: certificate
- name: SSH
include_tasks: ssh_port.yml
tags: ssh
- name: Kernel
include_tasks: kernel.yml
tags: kernel
Expand Down
7 changes: 7 additions & 0 deletions roles/common/tasks/ssh_port.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@
- 'ansible_distribution'
- 'ansible_distribution_major_version'

- name: "Common | SSH | Ensure ssh enabled and started"
become: true
service:
name: ssh
state: started
enabled: true

# We notified "Restart sshd" if we modified the sshd config.
# By calling flush_handlers, we make sure the handler is run *right now*
- name: "Common | SSH | Ensure SSH is reloaded if need be"
Expand Down
7 changes: 7 additions & 0 deletions roles/marzban/defaults/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ marzban_system_dirs:
- vault_dir: "/opt/marzban/credentials"
- work_dir: "/var/lib/marzban"
- certs_dir: "/var/lib/marzban/certs"
- templates_dir: "/var/lib/marzban/templates"

marzban_node_dirs:
- base_dir: "/opt/marzban"
Expand All @@ -13,8 +14,10 @@ marzban_node_dirs:
marzban_ssl_certfile: "{{ vault_ssl_certs.keys() | select('search', 'cert') | list | first }}"
marzban_ssl_keyfile: "{{ vault_ssl_certs.keys() | select('search', 'key') | list | first }}"

marzban_image: "gozargah/marzban"
marzban_image_tag: "latest"

marzban_haproxy_image: "haproxy"
marzban_haproxy_image_tag: "2.4.25"
marzban_haproxy_dirs:
- etc_dir: "/etc/haproxy"
Expand Down Expand Up @@ -82,6 +85,7 @@ marzban_docs: false
### Mysql(mariadb) configuration

marzban_mysql_instance: false
marzban_mysql_image: "mariadb"
marzban_mysql_image_tag: "lts"
marzban_mysql_db_name: "marzban"
marzban_mysql_user_name: "marzban"
Expand All @@ -104,3 +108,6 @@ marzban_backup_cron: { minute: "0", hour: "2", day: "*", month: "*", weekday: "*
marzban_ssl_node_path: "/var/lib/marzban-node/ssl_client_cert.pem"
marzban_ssl_node_certificate: ""
marzban_nodes_host_info: ""

marzban_node_image: "gozargah/marzban-node"
marzban_node_image_tag: "latest"
535 changes: 535 additions & 0 deletions roles/marzban/files/index.html

Large diffs are not rendered by default.

170 changes: 85 additions & 85 deletions roles/marzban/files/marzban_backup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,114 +25,114 @@ HOSTNAME_NODE=$(hostname)

# Logging function with levels and colors
log() {
LEVEL="$1"
MSG="$2"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
case "${LEVEL}" in
INFO)
printf "[${TIMESTAMP}] [${FontColor_Green}${LEVEL}${FontColor_Suffix}] %s\n" "${MSG}" | tee -a "$LOG_FILE"
;;
WARN)
printf "[${TIMESTAMP}] [${FontColor_Yellow}${LEVEL}${FontColor_Suffix}] %s\n" "${MSG}" | tee -a "$LOG_FILE"
;;
ERROR)
printf "[${TIMESTAMP}] [${FontColor_Red}${LEVEL}${FontColor_Suffix}] %s\n" "${MSG}" | tee -a "$LOG_FILE" >&2
;;
*)
printf "[${TIMESTAMP}] %s\n" "${MSG}" | tee -a "$LOG_FILE"
;;
esac
LEVEL="$1"
MSG="$2"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
case "${LEVEL}" in
INFO)
printf "[${TIMESTAMP}] [${FontColor_Green}${LEVEL}${FontColor_Suffix}] %s\n" "${MSG}" | tee -a "$LOG_FILE"
;;
WARN)
printf "[${TIMESTAMP}] [${FontColor_Yellow}${LEVEL}${FontColor_Suffix}] %s\n" "${MSG}" | tee -a "$LOG_FILE"
;;
ERROR)
printf "[${TIMESTAMP}] [${FontColor_Red}${LEVEL}${FontColor_Suffix}] %s\n" "${MSG}" | tee -a "$LOG_FILE" >&2
;;
*)
printf "[${TIMESTAMP}] %s\n" "${MSG}" | tee -a "$LOG_FILE"
;;
esac
}

# Function to create backup directory
create_backup_dir() {
if [ ! -d "$BACKUP_DIR" ]; then
log INFO "Creating backup directory: $BACKUP_DIR"
mkdir -p "$BACKUP_DIR"
fi
if [ ! -d "$BACKUP_DIR" ]; then
log INFO "Creating backup directory: $BACKUP_DIR"
mkdir -p "$BACKUP_DIR"
fi
}

# Function to backup directories
backup_directories() {
create_backup_dir
BACKUP_PATH="$BACKUP_DIR/backup_$CURRENT_DATE"
log INFO "Backing up directories to $BACKUP_PATH"
create_backup_dir
BACKUP_PATH="$BACKUP_DIR/backup_$CURRENT_DATE"
log INFO "Backing up directories to $BACKUP_PATH"

# Create directory structure for backup
mkdir -p "$BACKUP_PATH/lib"
mkdir -p "$BACKUP_PATH/opt"
# Create directory structure for backup
mkdir -p "$BACKUP_PATH/lib"
mkdir -p "$BACKUP_PATH/opt"

# Backup contents
cp -r $LIB_SRC_DIR "$BACKUP_PATH/lib/" || log WARN "Failed to backup lib directory."
cp -r $OPT_SRC_DIR "$BACKUP_PATH/opt/" || log WARN "Failed to backup opt directory."
# Backup contents
cp -r $LIB_SRC_DIR "$BACKUP_PATH/lib/" || log WARN "Failed to backup lib directory."
cp -r $OPT_SRC_DIR "$BACKUP_PATH/opt/" || log WARN "Failed to backup opt directory."

log INFO "Directories backed up successfully."
log INFO "Directories backed up successfully."
}

# Function to backup MySQL databases
backup_databases() {
if grep -q "SQLALCHEMY_DATABASE_URL" "$ENV_FILE" && ! grep -q "sqlite" "$ENV_FILE"; then
# Fixed user root
DB_USER="root"

# Extract root password from environment file
DB_PASSWORD=$(grep -oP '(?<=ROOT_PASSWORD=).*' "$ENV_FILE")

# Install mysqldump if not installed
if ! command -v mysqldump &> /dev/null; then
log WARN "mysqldump not found, installing..."
apt-get update && apt-get install -y mysql-client || log ERROR "Failed to install mysql-client."
fi

# Dump databases
DB_BACKUP_PATH="$BACKUP_PATH/db-backup"
mkdir -p "$DB_BACKUP_PATH"

# Get the list of databases and exclude system databases
databases=$(mysql -h 127.0.0.1 --user="$DB_USER" --password="$DB_PASSWORD" -e "SHOW DATABASES;" | tr -d "| " | grep -v -E 'Database|information_schema|mysql|performance_schema|sys')

for db in $databases; do
log INFO "Dumping database: $db"
# Use additional parameters to avoid errors
mysqldump -h 127.0.0.1 --force --opt --user="$DB_USER" --password="$DB_PASSWORD" --single-transaction --skip-lock-tables --no-tablespaces --databases "$db" > "$DB_BACKUP_PATH/$db.sql" || log ERROR "Getting some error while dump database: $db"
done
log INFO "Databases dumped successfully."
else
log INFO "SQLite detected or SQLALCHEMY_DATABASE_URL not found. No MySQL databases to backup."
fi
if grep -q "SQLALCHEMY_DATABASE_URL" "$ENV_FILE" && ! grep -q "sqlite" "$ENV_FILE"; then
# Fixed user root
DB_USER="root"

# Extract root password from environment file
DB_PASSWORD=$(grep -oP '(?<=ROOT_PASSWORD=).*' "$ENV_FILE")

# Install mysqldump if not installed
if ! command -v mysqldump &>/dev/null; then
log WARN "mysqldump not found, installing..."
apt-get update && apt-get install -y mysql-client || log ERROR "Failed to install mysql-client."
fi

# Dump databases
DB_BACKUP_PATH="$BACKUP_PATH/db-backup"
mkdir -p "$DB_BACKUP_PATH"

# Get the list of databases and exclude system databases
databases=$(mysql -h 127.0.0.1 --user="$DB_USER" --password="$DB_PASSWORD" -e "SHOW DATABASES;" | tr -d "| " | grep -v -E 'Database|information_schema|mysql|performance_schema|sys')

for db in $databases; do
log INFO "Dumping database: $db"
# Use additional parameters to avoid errors
mysqldump -h 127.0.0.1 --force --opt --user="$DB_USER" --password="$DB_PASSWORD" --single-transaction --skip-lock-tables --no-tablespaces --databases "$db" >"$DB_BACKUP_PATH/$db.sql" || log ERROR "Getting some error while dump database: $db"
done
log INFO "Databases dumped successfully."
else
log INFO "SQLite detected or SQLALCHEMY_DATABASE_URL not found. No MySQL databases to backup."
fi
}

# Function to send backup to Telegram
send_to_telegram() {
# Extract Telegram bot token and chat ID from environment file
TELEGRAM_BOT_TOKEN=$(grep -oP '(?<=TELEGRAM_BOT_TOKEN=).*' "$ENV_FILE")
TELEGRAM_CHAT_ID=$(grep -oP '(?<=TELEGRAM_CHAT_ID=).*' "$ENV_FILE")

if [ -n "$TELEGRAM_BOT_TOKEN" ] && [ -n "$TELEGRAM_CHAT_ID" ]; then
TAR_FILE="$BACKUP_DIR/backup_$CURRENT_DATE.tar.gz"
log INFO "Creating tarball $TAR_FILE"
tar -czf "$TAR_FILE" -C "$BACKUP_DIR" "backup_$CURRENT_DATE" || log ERROR "Failed to create tarball."

log INFO "Sending backup to Telegram chat ID $TELEGRAM_CHAT_ID"
curl -F chat_id="${TELEGRAM_CHAT_ID}" \
-F caption="Backup from $HOSTNAME_NODE at $CURRENT_DATE" \
-F parse_mode="HTML" \
-F document=@"$TAR_FILE" \
https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendDocument || log ERROR "Failed to send backup to Telegram."

log INFO "Backup sent to Telegram successfully."
else
log WARN "Telegram BOT token or chat ID not provided. Skipping upload."
fi
# Extract Telegram bot token and chat ID from environment file
TELEGRAM_BOT_TOKEN=$(grep -oP '(?<=TELEGRAM_BOT_TOKEN=).*' "$ENV_FILE")
TELEGRAM_CHAT_ID=$(grep -oP '(?<=TELEGRAM_CHAT_ID=).*' "$ENV_FILE")

if [ -n "$TELEGRAM_BOT_TOKEN" ] && [ -n "$TELEGRAM_CHAT_ID" ]; then
TAR_FILE="$BACKUP_DIR/backup_$CURRENT_DATE.tar.gz"
log INFO "Creating tarball $TAR_FILE"
tar -czf "$TAR_FILE" -C "$BACKUP_DIR" "backup_$CURRENT_DATE" || log ERROR "Failed to create tarball."

log INFO "Sending backup to Telegram chat ID $TELEGRAM_CHAT_ID"
curl -F chat_id="${TELEGRAM_CHAT_ID}" \
-F caption="Backup from $HOSTNAME_NODE at $CURRENT_DATE" \
-F parse_mode="HTML" \
-F document=@"$TAR_FILE" \
https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendDocument || log ERROR "Failed to send backup to Telegram."

log INFO "Backup sent to Telegram successfully."
else
log WARN "Telegram BOT token or chat ID not provided. Skipping upload."
fi
}

# Main backup process
main() {
log INFO "Starting backup process."
backup_directories
backup_databases
send_to_telegram
log INFO "Backup process completed."
log INFO "Starting backup process."
backup_directories
backup_databases
send_to_telegram
log INFO "Backup process completed."
}

# Run the main process
Expand Down
8 changes: 8 additions & 0 deletions roles/marzban/tasks/backup.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
---

- name: "Marzban | Backup | Prepare | Install cli utility"
apt:
name:
- mysql-client
state: present
update_cache: true
when: marzban_mysql_instance is defined and marzban_mysql_instance

- name: "Marzban | Backup | Add backup script"
copy:
src: "marzban_backup.sh"
Expand Down
20 changes: 16 additions & 4 deletions roles/marzban/tasks/conf/panel.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,18 @@

- name: "Marzban | Configure {{ role | upper() }} | Info"
debug:
msg: "Get gozargah/marzban docker image..."
msg: |
INFO:
--------------------------------------------
Get marzban docker image...
Image name: {{ marzban_image }}
Image tag: {{ marzban_image_tag }}
--------------------------------------------
changed_when: false
when: not key_stat.stat.exists

- name: "Marzban | Configure {{ role | upper() }} | Generate X25519 key if it does not exist"
command: "docker run --rm gozargah/marzban xray x25519"
command: "docker run --rm {{ marzban_image }} xray x25519"
register: generate_key_result
changed_when: false
when: not key_stat.stat.exists
Expand Down Expand Up @@ -75,9 +81,16 @@
src: "{{ item.src }}"
dest: "{{ marzban_system_dirs | json_query('[*].work_dir') | first }}/{{ item.dst }}"
mode: "{{ item.mode }}"
validate: /usr/bin/jq empty %s
loop:
- {src: xray_config.json.j2, dst: xray_config.json, mode: "0644"}

- name: "Marzban | Configure {{ role | upper() }} | Add subscription template"
copy:
src: "index.html"
dest: "{{ marzban_system_dirs | json_query('[*].templates_dir') | first }}/index.html"
mode: "0644"

- name: "Marzban | Configure {{ role | upper() }} | Template ssl certificate"
copy:
dest: "{{ (marzban_system_dirs | json_query('[*].certs_dir') | first) }}/{{ item.key }}"
Expand All @@ -88,7 +101,6 @@
content: "{{ item.value }}"
loop: "{{ vault_ssl_certs | dict2items }}"


- name: "Marzban | Configure {{ role | upper() }} | Create and start services"
community.docker.docker_compose_v2:
project_src: "{{ marzban_system_dirs | json_query('[*].base_dir') | first }}"
Expand All @@ -106,7 +118,7 @@
accept: "application/json"
Content-Type: "application/x-www-form-urlencoded"
body:
grant_type: ""
grant_type: "password"
username: "{{ marzban_panel_login }}"
password: "{{ marzban_panel_password }}"
scope: ""
Expand Down
Loading

0 comments on commit c921411

Please sign in to comment.