A detailed guide to setting up common services for a home server, including but not limited to samba file sharing, FTP server, FRP internal penetration, AdGuard Home ad filtering, qBittorrent Web downloader, etc.; the text editor used in this article is vim, if you are not familiar with the relevant usage, you can use other editors or search for relevant commands and usages on Baidu, this article will not elaborate further; the following content is fully applicable in the Ubuntu 20.04 LTS Server system, other Linux systems may have slight differences in configuration due to differences in package management tools and software installation paths.
TIP: The corresponding video of this article can be watched on Bilibili Linux Server Application Setup Tutorial [1]
1. SAMBA File Sharing
Samba allows Windows to access Linux resources, enabling data interaction between the two systems. The samba service program has become the best choice for sharing files between Linux and Windows systems, but the data transfer speed of clients based on the SMB2.0 protocol may not be as fast as FTP.
1.1 Install Samba
sudo apt install samba
1.2 Modify Configuration File
sudo vim /etc/samba/smb.conf
Add the following configuration at the end of the file:
[share]
# Name can be anything
comment = samba home directory
# Absolute path of the shared directory
path = /home/share/smb/disk
public = yes
browseable = yes
read only = no
guest ok = no
# Choose a local user as the login username, note that this is an example using share, which will be used later
valid users = share
# File permission control
create mask = 0755
# Directory permission control
directory mask = 0755
available = yes
# Disable asynchronous reading
aio read size = 0
1.3 Check Configuration File
Use the testparm
command to check if the added configuration is correct. If the following prompt appears, it indicates that the configuration is usable.
➜ ~ testparmLoad smb config files from /etc/samba/smb.confLoaded services file OK.Weak crypto is allowedServer role: ROLE_STANDALONEPress enter to see a dump of your service definitions
1.4 Start Samba Service and Set to Start on Boot
# Start the service
sudo systemctl start smbd
# Set to start on boot
sudo systemctl enable smbd
# Check service status
sudo systemctl status smbd
1.5 Configure Login Password for Users and Restart Service
# Configure access password
sudo smbpasswd -a <user> # <user> is the username share configured in the previous configuration file, the command will prompt to set a password
# Note that the password input is not displayed by default:
➜ ~ sudo smbpasswd -a share
New SMB password:
Retype new SMB password:
# After the password is configured, restart the service
sudo systemctl restart smbd
1.6 Test if Samba Works Properly
Add a network drive
Enter the server hostname or IP address + directory name, then enter the username and password
2. FTP Server
FTP (File Transfer Protocol) is one of the oldest protocols, mainly used for file transfer, especially convenient for transferring large files.
2.1 Install vsftpd
sudo apt install vsftpd
2.2 Modify Configuration File
The following is the configuration of vsftpd, the basic configuration entries already exist, just uncomment or change the settings (the configuration file contains English explanations, I will add Chinese comments for some main configurations):
The following is the complete configuration file content👇
# Example config file /etc/vsftpd.conf
#
# The default compiled in settings are fairly paranoid. This sample file
# loosens things up a bit, to make the ftp daemon more usable.
# Please see vsftpd.conf.5 for all compiled in defaults.
#
# READ THIS: This example file is NOT an exhaustive list of vsftpd options.
# Please read the vsftpd.conf.5 manual page to get a full idea of vsftpd's
# capabilities.
#
# Run standalone? vsftpd can run either from an inetd or as a standalone
# daemon started from an initscript.
# Run vsftpd in standalone mode
listen=YES
#
# This directive enables listening on IPv6 sockets. By default, listening
# on the IPv6 "any" address (::) will accept connections from both IPv6
# and IPv4 clients. It is not necessary to listen on *both* IPv4 and IPv6
# sockets. If you want that (perhaps because you want to listen on specific
# addresses) then you must run two copies of vsftpd with two configuration
# files.
#listen_ipv6=NO
#
# Allow anonymous FTP? (Disabled by default).
# Disable anonymous login
anonymous_enable=NO
#
# Uncomment this to allow local users to log in.
# Allow local users to log in
local_enable=YES
#
# Uncomment this to enable any form of FTP write command.
# Allow writing, if you only want to read or download from the FTP server, you can change to NO
write_enable=YES
#
# Default umask for local users is 077. You may wish to change this to 022,
# if your users expect that (022 is used by most other ftpd's)
#local_umask=022
#
# Uncomment this to allow the anonymous FTP user to upload files. This only
# has an effect if the above global write enable is activated. Also, you will
# obviously need to create a directory writable by the FTP user.
#anon_upload_enable=YES
#
# Uncomment this if you want the anonymous FTP user to be able to create
# new directories.
#anon_mkdir_write_enable=YES
#
# Activate directory messages - messages given to remote users when they
# go into a certain directory.
# Welcome message setting, it will check if there is a .message file under the shared directory, if so, it will echo the content of this file
dirmessage_enable=YES
#
# If enabled, vsftpd will display directory listings with the time
# in your local time zone. The default is to display GMT. The
# times returned by the MDTM FTP command are also affected by this
# option.
# Use local time to display file date
use_localtime=YES
#
# Activate logging of uploads/downloads.
# Enable upload/download logging
xferlog_enable=YES
#
# Make sure PORT transfer connections originate from port 20 (ftp-data).
# Connect via port 20
connect_from_port_20=YES
#
# If you want, you can arrange for uploaded anonymous files to be owned by
# a different user. Note! Using "root" for uploaded files is not
# recommended!
#chown_uploads=YES
#chown_username=whoever
#
# You may override where the log file goes if you like. The default is shown
# below.
xferlog_file=/var/log/vsftpd.log
#
# If you want, you can have your log file in standard ftpd xferlog format.
# Note that the default log file location is /var/log/xferlog in this case.
#xferlog_std_format=YES
#
# You may change the default value for timing out an idle session.
#idle_session_timeout=600
#
# You may change the default value for timing out a data connection.
#data_connection_timeout=120
#
# It is recommended that you define on your system a unique user which the
# ftp server can use as a totally isolated and unprivileged user.
#nopriv_user=ftpsecure
#
# Enable this and the server will recognise asynchronous ABOR requests. Not
# recommended for security (the code is non-trivial). Not enabling it,
# however, may confuse older FTP clients.
#async_abor_enable=YES
#
# By default the server will pretend to allow ASCII mode but in fact ignore
# the request. Turn on the below options to have the server actually do ASCII
# mangling on files when in ASCII mode.
# Beware that on some FTP servers, ASCII support allows a denial of service
# attack (DoS) via the command "SIZE /big/file" in ASCII mode. vsftpd
# predicted this attack and has always been safe, reporting the size of the
# raw file.
# ASCII mangling is a horrible feature of the protocol.
#ascii_upload_enable=YES
#ascii_download_enable=YES
#
# You may fully customise the login banner string:
#ftpd_banner=Welcome to blah FTP service.
#
# You may specify a file of disallowed anonymous e-mail addresses. Apparently
# useful for combatting certain DoS attacks.
deny_email_enable=YES
# (default follows)
banned_email_file=/etc/vsftpd.banned_emails
#
# You may restrict local users to their home directories. See the FAQ for
# the possible risks in this before using chroot_local_user or
# chroot_list_enable below.
# Allow users to switch to the upper directory
chroot_local_user=YES
#
# You may specify an explicit list of local users to chroot() to their home
# directory. If chroot_local_user is YES, then this list becomes a list of
# users to NOT chroot().
# (Warning! chroot'ing can be very dangerous. If using chroot, make sure that
# the user does not have write access to the top level directory within the
# chroot)
# Enable specified user list file
chroot_list_enable=YES
# (default follows)
# User list file, please do not add users to this file before you understand the rules!!!
chroot_list_file=/etc/vsftpd.chroot_list
#
# Default directory after user login, if not set, it will be the home directory of the logged-in user
local_root=/home/share/smb/disk
#
# You may activate the "-R" option to the builtin ls. This is disabled by
# default to avoid remote users being able to cause excessive I/O on large
# sites. However, some broken FTP clients such as "ncftp" and "mirror" assume
# the presence of the "-R" option, so there is a strong case for enabling it.
#ls_recurse_enable=YES
#
# Customization
#
# Some of vsftpd's settings don't fit the filesystem layout by
# default.
#
# This option should be the name of a directory which is empty. Also, the
# directory should not be writable by the ftp user. This directory is used
# as a secure chroot() jail at times vsftpd does not require filesystem
# access.
secure_chroot_dir=/var/run/vsftpd/empty
#
# This string is the name of the PAM service vsftpd will use.
pam_service_name=vsftpd
#
# This option specifies the location of the RSA certificate to use for SSL
# encrypted connections.
# SFTP related configuration, FTP does not apply
rsa_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem
rsa_private_key_file=/etc/ssl/private/ssl-cert-snakeoil.key
ssl_enable=NO
allow_writeable_chroot=YES
#
# Uncomment this to indicate that vsftpd use a utf8 filesystem.
# Use utf-8 encoding
utf8_filesystem=YES
Note: If write_enable has been set to YES, please read the following instructions carefully to ensure the security of the server!!!
chroot_local_user and chroot_list_enable can be used together, the rules are as follows: 1. When chroot_list_enable=YES, chroot_local_user=YES, users listed in the vsftpd.chroot_list file can switch to other directories; users not listed in the file cannot switch to other directories. 2. When chroot_list_enable=YES, chroot_local_user=NO, users listed in the vsftpd.chroot_list file cannot switch to other directories; users not listed in the file can switch to other directories. 3. When chroot_list_enable=NO, chroot_local_user=YES, all users cannot switch to other directories. 4. When chroot_list_enable=NO, chroot_local_user=NO, all users can switch to other directories.
2.3 Restart vsftpd Service
sudo service vsftpd restart
2.4 Test if the Configuration is Normal
If the configuration is normal but you still cannot log in to FTP and SSH login has been configured, please check the /etc/ssh/sshd_config
configuration file and comment out all SFTP service configurations in it.
# SFTP serviceSubsystem sftp internal-sftp Match Group share ChrootDirectory /home/share/sftp ForceCommand internal-sftp PasswordAuthentication yes PermitTunnel no X11Forwarding no AllowTcpForwarding no AllowAgentForwarding no
3. FRP Internal Penetration
Currently, most home broadband in China is behind a large internal network. If you want to access internal devices from the public network, internal penetration technology becomes particularly important; the internal penetration service used by the author is Sakura FRP[2], ordinary users can create two tunnels for free, with 5G traffic per month, and daily sign-in will give 1-4G traffic, 10Mb bandwidth is basically sufficient for personal use.
Ordinary User | Bronze VIP | Silver VIP | |
Normal speed limit | 10 Mibps | 24 Mibps | 36 Mibps |
Tunnel count | 2 | 2 + 8 additional tunnels | 2 + 8 additional tunnels |
Monthly base traffic | 5 GiB | 5 GiB | 5 GiB |
Monthly awarded traffic package | ❌ | 66 GiB | 88 GiB |
Unlock VIP nodes | ❌ | ✔️ | ✔️ |
Purchase additional tunnels | ❌ | ✔️ | ✔️ |
Unlock advanced nodes | ❌ | ❌ | ✔️ |
3.1 Register and Download Client Software
Visit Sakura FRP[3] official website to register an account and log in, complete real-name authentication after paying one yuan, and then find the software download in the service section
Select the corresponding software version according to the system version or copy the download link
Use the wget
command to download to the server and save it as /usr/local/bin/frpc for backup
➜ ~ wget https://getfrp.sh/d/frpc_linux_amd64
--2022-12-29 23:20:58-- https://getfrp.sh/d/frpc_linux_amd64
Resolving host getfrp.sh (getfrp.sh)... 2606:4700:3037::ac43:95bc, 2606:4700:3037::6815:1dc6, 172.67.149.188, ...
Connecting to getfrp.sh (getfrp.sh)|2606:4700:3037::ac43:95bc|:443... Connected.
Sent HTTP request, waiting for response... 302 Moved Temporarily
Location: https://nyat-static.globalslb.net/natfrp/client/0.45.0-sakura-1/frpc_linux_amd64 [following to new URL]
--2022-12-29 23:20:59-- https://nyat-static.globalslb.net/natfrp/client/0.45.0-sakura-1/frpc_linux_amd64
Resolving host nyat-static.globalslb.net (nyat-static.globalslb.net)... 240e:914:6:d:37b3:771e:6811:fffe, 153.35.50.206
Connecting to nyat-static.globalslb.net (nyat-static.globalslb.net)|240e:914:6:d:37b3:771e:6811:fffe|:443... Connected.
Sent HTTP request, waiting for response... 200 OK
Length: 4556856 (4.3M) [application/octet-stream]
Saving to: ‘frpc_linux_amd64’
frpc_linux_amd64 100%[=================================================>] 4.35M 12.3MB/s Time: 0.4s
2022-12-29 23:21:00 (12.3 MB/s) - Saved ‘frpc_linux_amd64’ [4556856/4556856])
➜ ~ sudo mv ./frpc_linux_amd64 /usr/local/bin/frpc
➜ ~
3.2 Create Tunnel
Before creating a tunnel, you need to complete real-name authentication in User-Real-name Authentication
Create a tunnel in Service-Tunnel List
Select the appropriate node based on the type of demand, taking Zaozhuang Multi-line 2 as an example (using SSH)
Select TCP tunnel type, use the default local IP, select port 22, and then create the tunnel
After the tunnel is created, it will display the tunnel’s ID and external access port, these two parameters will be used later!
3.3 Configure Local Service
In the User-User Information page, check the access key for backup, Note: The access key is an important parameter for using the tunnel, do not leak it to anyone!!!
Use the command sudo vim /etc/systemd/system/frpc.service
to edit a frpc.service
service file in the /etc/systemd/system/
directory
The file content is as follows:
[Unit]
Description=SakuraFrp Service
After=network.target
[Service]
Type=idle
User=nobody
Restart=on-failure
RestartSec=60s
#/usr/local/bin/frpc is the absolute path of the downloaded FRP file
# The same node supports starting multiple tunnels, the parameter is -f <access key>:<tunnel ID>,<tunnel ID>,...
ExecStart=/usr/local/bin/frpc -f 8**************d:1****6,1****0,1*****3,1*****2
[Install]
WantedBy=multi-user.target
Then execute the following commands in order
# Update service configuration
sudo systemctl daemon-reload
# Start FRP service
sudo systemctl start frpc
# Set service to start on boot
sudo systemctl enable frpc
# Check service status
sudo systemctl status frpc
If the service status shows similar prompts (some information has been desensitized), the tunnel has started successfully.
● frpc.service - SakuraFrp Service
Loaded: loaded (/lib/systemd/system/frpc.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2022-12-25 22:07:20 CST; 4 days ago
Main PID: 710 (frpc)
Tasks: 10 (limit: 4561)
Memory: 18.2M
CPU: 2min 32.520s
CGroup: /system.slice/frpc.service
└─710 /usr/local/bin/frpc -f 8*************b:1*****6,1*****0,1*****3
Dec 29 18:02:05 ubuntu frpc[710]: TCP type tunnel started successfully
Dec 29 18:02:05 ubuntu frpc[710]: Use [********.natfrp.cloud:2***5] to connect to your tunnel
Dec 29 18:02:05 ubuntu frpc[710]: Or use the IP address to connect (not recommended): [***.***.***.***:2***5]
Dec 29 18:02:05 ubuntu frpc[710]: 2022/12/29 18:02:05 [I] [44/*****/****] [9******5.***] start proxy success
Dec 29 18:02:05 ubuntu frpc[710]: TCP type tunnel started successfully
Dec 29 18:02:05 ubuntu frpc[710]: Use [********.natfrp.cloud:2***5] to connect to your tunnel
Dec 29 18:02:05 ubuntu frpc[710]: Or use the IP address to connect (not recommended): [***.***.***.***:2***5]
Dec 29 18:02:05 ubuntu frpc[710]: 2022/12/29 18:02:05 [I] [44/*****/****] start proxy success
Dec 29 18:02:05 ubuntu frpc[710]: 2022/12/29 18:02:05 [I] [44/*****/****] speed limit has been updated: 10 Mibit/s
Dec 29 23:58:30 ubuntu systemd[1]: /lib/systemd/system/frpc.service:7: Special user nobody configured, this is not safe
lines 1-20/20 (END)
The prompt will have similar usage tunnel prompt, indicating the tunnel’s external access address and port.
Use [**********.natfrp.cloud:3*****6] to connect to your tunnel
3.4 Test Tunnel Connection
Use the link and port prompted above to try to connect to the Ubuntu server via SSH, if you see a prompt for entering the key password, it indicates that the tunnel has started successfully!
4. AdGuard Home
Home networks usually use optical modems for dialing, defaulting to using DNS (Domain Name Server) servers provided by ISPs (Internet Service Providers), as DNS pollution is serious, causing some websites (like GitHub) to often resolve to incorrect IP addresses, resulting in websites being inaccessible.
AdGuard Home is an open-source private DNS server from AdGuard that can achieve global ad blocking and privacy anti-tracking simply by deploying it at the gateway. During the DNS resolution process, it intercepts URLs that match the rule library, and at the client level, it can also implement webpage DOM interception through custom filtering rules.
AdGuard Home is a network-wide ad blocking and anti-tracking software. Once you install it, it will protect all your home devices, and you no longer need to install any client software. With the rise of IoT and connected devices, controlling your own entire network environment is becoming increasingly important. — AdGuard Home
4.1 Install AdGuard Home
Go to the GitHub homepage of AdGuard Home[4], the README.md provides an automated installation script
Just execute the installation command it provides (requires root permission)
sudo curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v
If the server refuses to connect during execution, you can edit the configuration file /etc/systemd/resolved.conf
and change the DNS to any of the following DNS addresses, then re-execute
Some available DNS:cloudflare DNS: 1.0.0.1 , 1.1.1.1Google Public DNS: 8.8.8.8 , 8.8.4.4Baidu Public DNS: 180.76.76.76DNSPod (Tencent) DNS: 119.29.29.29Aliyun DNS: 223.5.5.5 , 223.6.6.614 DNS: 117.50.10.10DNS派 Telecom DNS: 101.226.4.6 , Mobile DNS: 218.30.118.6114 DNS: 114.114.114.114 , 114.114.115.115
The script will automatically install, configure, and start the service. Execute sudo systemctl status AdGuardHome.service
to check the service running status
➜ ~ sudo systemctl status AdGuardHome.service
● AdGuardHome.service - AdGuard Home: Network-level blocker
Loaded: loaded (/etc/systemd/system/AdGuardHome.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2022-12-31 06:01:04 CST; 15h ago
Main PID: 694 (AdGuardHome)
Tasks: 12 (limit: 4561)
Memory: 63.8M
CPU: 4min 40.054s
CGroup: /system.slice/AdGuardHome.service
└─694 /home/tyler/AdGuardHome/AdGuardHome -s run
Dec 31 06:01:04 ubuntu systemd[1]: Started AdGuard Home: Network-level blocker.
➜ ~
4.2 Set Up AdGuard Home and Add Blocking Rules
The AdGuard Home web interface is defaulted to port 3000, accessible via the server IP:3000; if the web page cannot be accessed, please check if the firewall has port 3000 open, the command to open port 3000 in Ubuntu firewall issudo ufw allow 3000
. The first visit will guide the user to configure the login password

80 is the default port for HTTP websites, if your server has plans to build a website, it is recommended not to set the web management interface port to 80; the client accesses DNS using port 53, to avoid unnecessary trouble, do not modify the DNS server’s listening port! Additionally, as a DNS server, a static IP must be used; a change in server IP will cause domain name resolution to fail.

After configuring the username and password, you can access the management page, in Settings-DNS Settings you can configure upstream DNS

In Filters-DNS Interception List you can configure adblock rules and Hosts syntax
First Visit
Here are a few rules used by the author:
Chengfeng Ad: https://gitee.com/xinggsf/Adblock-Rule/raw/master/rule.txtChengfeng Video: https://gitee.com/xinggsf/Adblock-Rule/raw/master/mv.txtAd Blocker: http://sub.adtchrome.com/adt-chinalist-easylist360.txtEasyList China: https://easylist-downloads.adblockplus.org/easylistchina.txtMacau Royal Casino Specific Blocking Rules: https://raw.githubusercontent.com/Goooler/1024_hosts/master/hostsCHN: AdRules DNS List: https://adguardteam.github.io/HostlistsRegistry/assets/filter_29.txtCHN: anti-AD: https://adguardteam.github.io/HostlistsRegistry/assets/filter_21.txtZhihu Ads: https://cdn.jsdelivr.net/gh/zsakvo/AdGuard-Custom-Rule@master/rule/zhihu-strict.txtChinaList+EasyList (Qi): http://sub.adtchrome.com/adt-chinalist-easylist.txtEasyPrivacy: https://easylist-downloads.adblockplus.org/easyprivacy.txt
4.3 Set Default DNS Server
Directly set the DHCP server of the router (taking Xiaomi router as an example, as I am using Xiaomi 😼), log into the router’s backend, and in Common Settings-LAN Settings-DHCP Service set DNS1 to the server’s address. If the server runs 24/7, DNS2 does not need to be set, after saving the settings, devices connected to this router will use AdGuard Home as the DNS server.

4.4 Test DNS Server
Devices not using AdGuard Home server:
# Use nslookup command to query the IP address of the GitHub material server raw.githubusercontent.com, the result is 0.0.0.0
➜ ~ nslookup raw.githubusercontent.com
Server: 192.168.1.1
Address: 192.168.1.1#53
Non-authoritative answer:
Name: raw.githubusercontent.com
Address: 0.0.0.0
Name: raw.githubusercontent.com
Address: ::
# cm.ipinyou.com is a domain name for a video ad, using nslookup command to query can get the IP
➜ ~ nslookup cm.ipinyou.com
Server: 192.168.1.1
Address: 192.168.1.1#53
Non-authoritative answer:
Name: cm.ipinyou.com
Address: 152.136.199.109
Name: cm.ipinyou.com
Address: 152.136.179.124
Name: cm.ipinyou.com
Address: 152.136.187.208
Devices using AdGuard Home server:
➜ ~ nslookup raw.githubusercontent.com
Server: UnKnown
Address: 192.168.31.52
Non-authoritative answer:
Name: raw.githubusercontent.com
Addresses: 2606:50c0:8003::154
2606:50c0:8000::154
2606:50c0:8002::154
185.199.111.133
185.199.110.133
185.199.108.133
185.199.109.133
➜ ~ nslookup cm.ipinyou.com
Server: UnKnown
Address: 192.168.31.52
*** UnKnown cannot find cm.ipinyou.com: Query refused
By comparing, it is not difficult to find that AdGuard Home can avoid DNS pollution and achieve ad filtering.
5. qBittorrent Web UI
Initially, I used the web version of the downloader transmission, but transmission has a very troublesome drawback, which is that it cannot automatically add trackers, requiring manual addition every time a download is initiated; I have tried using scripts to add them automatically, but the effect is not very good, so I switched to qbittorrent-nox 🥲
5.1 Install qbittorrent-nox
A single command sudo apt install qbittorrent-nox
is sufficient, but this version in the software repository seems to have some bugs, and adding multiple torrents in the Web UI easily causes it to freeze, so this article also provides methods for installing the latest stable and testing versions of the software:
# Add software common properties to facilitate apt management
sudo apt install software-properties-common
# Add qBittorrent stable version software source (choose one)
sudo add-apt-repository ppa:qbittorrent-team/qbittorrent-stable
# Add qBittorrent testing version software source (choose one)
sudo add-apt-repository ppa:qbittorrent-team/qbittorrent-unstable
# Update software source information
sudo apt update
# Install
sudo apt install qbittorrent-nox
5.2 Add System Service
Write a /etc/systemd/system/qbittorrent-nox.service
file, the content is as follows:
[Unit]
Description=qBittorrent Command Line Client
After=network.target
[Service]
# Do not change to "simple"
Type=forking
# User specifies which local user to start qBittorrent, the generated configuration file will be saved in the corresponding user's home directory
User=share
RemainAfterExit=yes
ExecStart=/usr/bin/qbittorrent-nox -d
Restart=on-failure
[Install]
WantedBy=multi-user.target
Start the service and set it to start on boot
# Start the service
sudo systemctl start qbittorrent-nox.service
# Check service status
sudo systemctl status qbittorrent-nox.service
# Add to start on boot
sudo systemctl enable qbittorrent-nox.service
5.3 Configuration and Optimization
The Web UI listens on port 8080 by default, accessible via IP:8080, the first visit has the username as admin and password as adminadmin. Directly adding torrents or magnets may not yield download speeds; trackers need to be added, the trackers in the image can be found on GitHub[5].
Trackers
The built-in Web UI is not optimized for mobile devices, you can use third-party UI beautification packages[6], download the ZIP package and unzip it on the server

In the settings under the Web UI tab, enable the alternative Web UI and fill in the absolute path of the unzipped resources, save to enable the new UI

The optimized UI is much more aesthetically pleasing, but the downside is that some features have been removed

If you cannot access the WEB UI interface due to configuration errors, you can manually add the following code after the URL to disable the alternative UI function.
/api/v2/app/setPreferences?json=%7B%22alternative_webui_enabled%22:false%7D
Reference Links
[1]
Linux Server Application Setup Tutorial: https://www.bilibili.com/video/BV1HS4y1S7P9[2]
Sakura FRP: https://www.natfrp.com/[3]
Sakura FRP: https://www.natfrp.com/[4]
AdGuard Home GitHub Homepage: https://github.com/AdguardTeam/AdGuardHome[5]
trackerslist: https://github.com/ngosang/trackerslist[6]
UI Beautification Package: https://github.com/CzBiX/qb-web/releases