Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deploy/docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ ENV TZ=Etc/UTC

RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y unbound iproute2 iptables supervisor wget dnsmasq && \
apt-get install -y unbound dnsmasq iproute2 iptables supervisor wget iputils-ping && \
apt-get clean && \
rm -rf /var/lib/apt/lists/*

Expand Down
5 changes: 4 additions & 1 deletion deploy/docker/scripts/start-fptn.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ exec /usr/local/bin/fptn-server \
--remote-server-auth-host="$REMOTE_SERVER_AUTH_HOST" \
--remote-server-auth-port="$REMOTE_SERVER_AUTH_PORT" \
--max-active-sessions-per-user="$MAX_ACTIVE_SESSIONS_PER_USER" \
--server-external-ips="${SERVER_EXTERNAL_IPS}"
--server-external-ips="${SERVER_EXTERNAL_IPS}" \
--client-dns-server-ipv4="${CLIENT_DNS_SERVER_IPV4}" \
--client-dns-server-ipv6="${CLIENT_DNS_SERVER_IPV6}"

19 changes: 19 additions & 0 deletions docker-compose/.env.demo
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# ============================================
# FPTN SERVER
# ============================================

# Directory used by FPTN to store configuration and runtime data
FPTN_CONFIGS_FOLDER=./fptn-server-data

# Port for FPTN server
FPTN_PORT=443

# Comma-separated list of server's public IPv4 addresses.
Expand Down Expand Up @@ -54,6 +59,20 @@ PROMETHEUS_SECRET_ACCESS_KEY=
# Maximum number of active sessions allowed per VPN user
MAX_ACTIVE_SESSIONS_PER_USER=3

# ============================================
# CLIENT DNS (OVERRIDE)
# ============================================
# Optional: explicitly set DNS server addresses for VPN clients.
#
# Default (empty):
# - The TUN interface address is used as the DNS server for clients
# - This means the DNS server running inside the container (configured above) will be used
#
# If set:
# - The specified DNS server addresses will be used instead of the container DNS
CLIENT_DNS_SERVER_IPV4=8.8.8.8
CLIENT_DNS_SERVER_IPV6=

# ============================================
# DNS SERVER
# ============================================
Expand Down
9 changes: 4 additions & 5 deletions docker-compose/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,9 @@ services:
net.ipv4.conf.all.rp_filter: "0"
net.ipv4.conf.default.rp_filter: "0"
# Network optimizations
net.ipv4.tcp_congestion_control: bbr
net.ipv4.ip_local_port_range: "1024 65535"
#net.ipv4.tcp_tw_reuse: "1"
#net.ipv4.tcp_fin_timeout: "15"
net.core.somaxconn: "65535"
#net.ipv4.tcp_max_syn_backlog: "16384"
#net.ipv4.tcp_slow_start_after_idle: "0"
ulimits:
nproc:
soft: 524288
Expand All @@ -37,7 +34,7 @@ services:
ports:
- "${FPTN_PORT}:443/tcp"
volumes:
- ./fptn-server-data:/etc/fptn
- ${FPTN_CONFIGS_FOLDER}:/etc/fptn
environment:
- ENABLE_DETECT_PROBING=${ENABLE_DETECT_PROBING}
- DEFAULT_PROXY_DOMAIN=${DEFAULT_PROXY_DOMAIN}
Expand All @@ -49,6 +46,8 @@ services:
- REMOTE_SERVER_AUTH_PORT=${REMOTE_SERVER_AUTH_PORT}
- MAX_ACTIVE_SESSIONS_PER_USER=${MAX_ACTIVE_SESSIONS_PER_USER}
- SERVER_EXTERNAL_IPS=${SERVER_EXTERNAL_IPS}
- CLIENT_DNS_SERVER_IPV4=${CLIENT_DNS_SERVER_IPV4:-}
- CLIENT_DNS_SERVER_IPV6=${CLIENT_DNS_SERVER_IPV6:-}
- USING_DNS_SERVER=${USING_DNS_SERVER:-dnsmasq}
- DNS_IPV4_PRIMARY=${DNS_IPV4_PRIMARY:-8.8.8.8}
- DNS_IPV4_SECONDARY=${DNS_IPV4_SECONDARY:-8.8.4.4}
Expand Down
17 changes: 13 additions & 4 deletions src/fptn-client/gui/tray/tray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,9 @@ bool TrayApp::startVpn(QString& err_msg) {
return false;
}

SPDLOG_INFO("DNS configuration loaded: IPv4='{}', IPv6='{}'",
dns_server_ipv4.ToString(), dns_server_ipv6.ToString());

const auto blacklist_domains = settings_->BlacklistDomains();
const auto exclude_networks = settings_->ExcludeTunnelNetworks();
const auto include_networks = settings_->IncludeTunnelNetworks();
Expand All @@ -819,9 +822,16 @@ bool TrayApp::startVpn(QString& err_msg) {

// route manager
route_manager_ = std::make_unique<fptn::routing::RouteManager>(
network_interface, tun_interface_name, server_ip, dns_server_ipv4,
dns_server_ipv6, gateway_ip, gateway_ipv6, tun_interface_address_ipv4,
tun_interface_address_ipv6
/* tun */
network_interface, tun_interface_name,
/* server */
server_ip,
/* dns */
dns_server_ipv4, dns_server_ipv6,
/* gateway */
gateway_ip, gateway_ipv6,
/* tun address */
tun_interface_address_ipv4, tun_interface_address_ipv6
#if _WIN32
,
settings_->EnableAdvancedDnsManagement()
Expand Down Expand Up @@ -898,7 +908,6 @@ bool TrayApp::startVpn(QString& err_msg) {
}
route_manager_->AddIncludeNetworks(include_networks_std);
}

return true;
}

Expand Down
30 changes: 30 additions & 0 deletions src/fptn-server/config/command_line_config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@ CommandLineConfig::CommandLineConfig(int argc, char* argv[])
" - Client SNI in list -> proxy to client's SNI\n"
" - Client SNI not in list -> proxy to --default-proxy-domain")
.default_value("");
// DNS settings for client
args_.add_argument("--client-dns-server-ipv4")
.help(
"Sets the IPv4 DNS server address used by the client. "
"If not provided, the TUN interface IPv4 address will be used.")
.default_value("");

args_.add_argument("--client-dns-server-ipv6")
.help(
"Sets the IPv6 DNS server address used by the client. "
"If not provided, the TUN interface IPv6 address will be used.")
.default_value("");
// Prevent self-proxy
args_.add_argument("--server-external-ips")
.help(
Expand Down Expand Up @@ -251,4 +263,22 @@ std::string CommandLineConfig::ServerExternalIPs() const {
return args_.get<std::string>("--server-external-ips");
}

[[nodiscard]]
IPv4Address CommandLineConfig::ClientDnsServerIPv4() const {
const auto param = args_.get<std::string>("--client-dns-server-ipv4");
if (!param.empty()) {
return IPv4Address(param);
}
return TunInterfaceIPv4();
}

[[nodiscard]]
IPv6Address CommandLineConfig::ClientDnsServerIPv6() const {
const auto param = args_.get<std::string>("--client-dns-server-ipv6");
if (!param.empty()) {
return IPv6Address(param);
}
return TunInterfaceIPv6();
}

} // namespace fptn::config
3 changes: 3 additions & 0 deletions src/fptn-server/config/command_line_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ class CommandLineConfig {

[[nodiscard]] std::string ServerExternalIPs() const;

[[nodiscard]] IPv4Address ClientDnsServerIPv4() const;
[[nodiscard]] IPv6Address ClientDnsServerIPv6() const;

private:
int argc_;
char** argv_;
Expand Down
7 changes: 5 additions & 2 deletions src/fptn-server/fptn-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,11 @@ int main(int argc, char* argv[]) {
/* Init webserver */
auto web_server = std::make_unique<fptn::web::Server>(config.ServerPort(),
nat_table, user_manager, token_manager, prometheus,
config.PrometheusAccessKey(), config.TunInterfaceIPv4(),
config.TunInterfaceIPv6(),
config.PrometheusAccessKey(),
/* DNS IPv4 */
config.ClientDnsServerIPv4(),
/* DNS IPv6 */
config.ClientDnsServerIPv6(),
/* probing */
config.EnableDetectProbing(), config.DefaultProxyDomain(),
config.AllowedSniList(),
Expand Down
4 changes: 1 addition & 3 deletions src/fptn-server/routing/iptables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,10 @@ bool RouteManager::Apply() { // NOLINT(bugprone-exception-escape)
#else
#error "Unsupported system!"
#endif
SPDLOG_INFO("=== Setting up routing ===");
try {
for (const auto& cmd : commands) {
if (!RunCommand(cmd)) {
SPDLOG_ERROR("COMMAND ERROR: {}", cmd);
SPDLOG_WARN("COMMAND ERROR: {}", cmd);
}
}
} catch (const std::exception& e) {
Expand All @@ -159,7 +158,6 @@ bool RouteManager::Apply() { // NOLINT(bugprone-exception-escape)
SPDLOG_ERROR("Unknown exception occurred while applying routing.");
return false;
}
SPDLOG_INFO("=== Routing setup completed successfully ===");
return true;
}

Expand Down
Loading