vpn settings

This commit is contained in:
arm64v8a
2022-08-05 17:07:32 +08:00
parent 77d354874e
commit efdac7fa6f
11 changed files with 320 additions and 139 deletions

View File

@@ -1,14 +1,11 @@
{
"dns": {
"servers": [],
"rules": [],
"strategy": "ipv4_only"
},
"inbounds": [
{
"type": "tun",
"interface_name": "nekoray-tun",
"inet4_address": "172.19.0.1/30",
%IPV6_ADDRESS%
"mtu": %MTU%,
"auto_route": true,
"sniff": false
}

View File

@@ -11,6 +11,7 @@ fi
[ -z $TABLE_FWMARK ] && echo "Please set env TABLE_FWMARK" && exit
[ -z $TUN_NAME ] && echo "Please set env TUN_NAME" && exit
[ -z $USER_ID ] && echo "Please set env USER_ID" && exit
[ -z $MTU ] && MTU=1500
command -v pkill >/dev/null 2>&1 || exit
BASEDIR=$(dirname "$0")
@@ -19,16 +20,22 @@ cd $BASEDIR
start() {
# add tun (TODO the ip must be the same as matsuri)
ip tuntap add $TUN_NAME mode tun user $USER_ID || return
ip addr add 172.19.0.1/30 dev $TUN_NAME || return
ip link set dev nekoray-tun mtu $MTU || return
ip link set dev $TUN_NAME up || return
# set ipv4 rule
ip addr add 172.19.0.1/30 dev $TUN_NAME || return
ip rule add table $TABLE_FWMARK || return
ip route add table $TABLE_FWMARK default dev $TUN_NAME || return
# set ipv6 unreachable
# set ipv6 rule
ip -6 rule add table $TABLE_FWMARK || return
ip -6 route add table $TABLE_FWMARK unreachable default || return
if [ -z $ENABLE_IPV6 ]; then
ip -6 route add table $TABLE_FWMARK unreachable default || return
else
ip -6 addr add fdfe:dcba:9876::1/126 dev $TUN_NAME || return
ip -6 route add table $TABLE_FWMARK default dev $TUN_NAME || return
fi
# set bypass: fwmark
ip rule add fwmark $TABLE_FWMARK table main || return
@@ -39,6 +46,10 @@ start() {
ip rule add to $local table main
done
# for Tun2Socket
iptables -I INPUT -s 172.19.0.2 -d 172.19.0.1 -p tcp -j ACCEPT
ip6tables -I INPUT -s fdfe:dcba:9876::2 -d fdfe:dcba:9876::1 -p tcp -j ACCEPT
if [ ! -z $USE_NEKORAY ]; then
"./nekoray_core" tool protect --protect-listen-path "$PROTECT_LISTEN_PATH" --protect-fwmark $TABLE_FWMARK
else
@@ -55,6 +66,8 @@ stop() {
for local in $BYPASS_IPS; do
ip rule del to $local table main
done
iptables -D INPUT -s 172.19.0.2 -d 172.19.0.1 -p tcp -j ACCEPT
ip6tables -D INPUT -s fdfe:dcba:9876::2 -d fdfe:dcba:9876::1 -p tcp -j ACCEPT
ip rule del table $TABLE_FWMARK
ip rule del fwmark $TABLE_FWMARK
ip route del table $TABLE_FWMARK default

View File

@@ -3,6 +3,7 @@ package main
import (
"errors"
"libcore"
"libcore/comm"
"nekoray_core/gen"
"sync"
"syscall"
@@ -33,6 +34,7 @@ func TunStart(config *gen.SetTunReq) (err error) {
V2Ray: instance, // use current if started
Implementation: config.Implementation,
Sniffing: true,
IPv6Mode: comm.IPv6Prefer,
FakeDNS: config.Fakedns,
})
return

View File

@@ -50,6 +50,9 @@ namespace NekoRay {
_add(new configItem("active_routing", &active_routing, itemType::string));
_add(new configItem("mw_size", &mw_size, itemType::string));
_add(new configItem("conn_stat", &connection_statistics, itemType::boolean));
_add(new configItem("vpn_impl", &vpn_implementation, itemType::integer));
_add(new configItem("vpn_mtu", &vpn_mtu, itemType::integer));
_add(new configItem("vpn_ipv6", &vpn_ipv6, itemType::boolean));
}
void DataStore::UpdateStartedId(int id) {

View File

@@ -42,6 +42,14 @@ namespace NekoRay {
int core_port = 19810;
int started_id = -1919;
Routing *routing = new Routing;
int imported_count = 0;
bool refreshing_group_list = false;
// Flags
bool flag_use_appdata = false;
bool flag_many = false;
// Saved
// Misc
@@ -91,6 +99,11 @@ namespace NekoRay {
QString custom_route_global = "{\"rules\": []}";
QString active_routing = "Default";
// VPN
int vpn_implementation = 0;
int vpn_mtu = 9000;
bool vpn_ipv6 = false;
// Hotkey
QString hotkey_mainwindow = "";
QString hotkey_group = "";
@@ -99,19 +112,6 @@ namespace NekoRay {
// Other Core
ExtraCore *extraCore = new ExtraCore;
// Running Cache
Routing *routing = new Routing;
int imported_count = 0;
bool refreshing_group_list = false;
// Running Flags
bool flag_use_appdata = false;
bool flag_many = false;
//
DataStore();
void UpdateStartedId(int id);

View File

@@ -450,6 +450,14 @@
<source>Custom (global)</source>
<translation> ()</translation>
</message>
<message>
<source>VPN Implementation</source>
<translation>VPN </translation>
</message>
<message>
<source>VPN Enable IPv6</source>
<translation> VPN IPv6</translation>
</message>
</context>
<context>
<name>EditChain</name>
@@ -1026,6 +1034,14 @@ End: %2</source>
<source>Enable VPN</source>
<translation> VPN</translation>
</message>
<message>
<source>VPN settings changed</source>
<translation>VPN </translation>
</message>
<message>
<source>Restart VPN to take effect.</source>
<translation> VPN </translation>
</message>
</context>
<context>
<name>ProxyItem</name>

View File

@@ -38,14 +38,22 @@ DialogManageRoutes::DialogManageRoutes(QWidget *parent) :
ui->dns_direct->setText(NekoRay::dataStore->direct_dns);
ui->enhance_resolve_server_domain->setChecked(NekoRay::dataStore->enhance_resolve_server_domain);
D_C_LOAD_STRING(custom_route_global)
//
ui->vpn_implementation->setCurrentIndex(NekoRay::dataStore->vpn_implementation);
ui->vpn_mtu->setCurrentText(Int2String(NekoRay::dataStore->vpn_mtu));
ui->vpn_ipv6->setChecked(NekoRay::dataStore->vpn_ipv6);
#ifdef Q_OS_WIN
ui->vpn_implementation->setEditable(true);
ui->vpn_implementation->setCurrentText("Windows: sing-box gVisor");
ui->vpn_implementation->setDisabled(true);
#endif
//
connect(ui->custom_route_edit, &QPushButton::clicked, this, [=] {
C_EDIT_JSON_ALLOW_EMPTY(custom_route)
});
connect(ui->custom_route_global_edit, &QPushButton::clicked, this, [=] {
C_EDIT_JSON_ALLOW_EMPTY(custom_route_global)
});
//
builtInSchemesMenu = new QMenu(this);
builtInSchemesMenu->addActions(this->getBuiltInSchemes());
@@ -81,19 +89,39 @@ void DialogManageRoutes::accept() {
NekoRay::dataStore->domain_strategy = ui->domainStrategyCombo->currentText();
NekoRay::dataStore->outbound_domain_strategy = ui->outbound_domain_strategy->currentText();
NekoRay::dataStore->dns_routing = ui->dns_routing->isChecked();
NekoRay::dataStore->fake_dns = ui->fake_dns->isChecked();
NekoRay::dataStore->remote_dns = ui->dns_remote->text();
NekoRay::dataStore->direct_dns = ui->dns_direct->text();
NekoRay::dataStore->enhance_resolve_server_domain = ui->enhance_resolve_server_domain->isChecked();
D_C_SAVE_STRING(custom_route_global)
//
bool vpnChanged = false;
auto fakedns = ui->fake_dns->isChecked();
auto mtu = ui->vpn_mtu->currentText().toInt();
if (mtu > 10000 || mtu < 1000) mtu = 9000;
auto ipv6 = ui->vpn_ipv6->isChecked();
#ifndef Q_OS_WIN
auto impl = ui->vpn_implementation->currentIndex();
vpnChanged |= NekoRay::dataStore->vpn_implementation != impl;
NekoRay::dataStore->vpn_implementation = impl;
#endif
vpnChanged |= NekoRay::dataStore->fake_dns != fakedns;
vpnChanged |= NekoRay::dataStore->vpn_mtu != mtu;
vpnChanged |= NekoRay::dataStore->vpn_ipv6 != ipv6;
NekoRay::dataStore->fake_dns = fakedns;
NekoRay::dataStore->vpn_mtu = mtu;
NekoRay::dataStore->vpn_ipv6 = ipv6;
//
bool routeChanged = false;
if (NekoRay::dataStore->active_routing != active_routing) routeChanged = true;
SAVE_TO_ROUTING(NekoRay::dataStore->routing)
NekoRay::dataStore->active_routing = active_routing;
NekoRay::dataStore->routing->fn = "routes/" + NekoRay::dataStore->active_routing;
NekoRay::dataStore->routing->Save();
dialog_message(Dialog_DialogManageRoutes, "UpdateDataStore");
if (NekoRay::dataStore->routing->Save()) routeChanged = true;
//
QString info = "UpdateDataStore";
if (routeChanged) info += "RouteChanged";
if (vpnChanged) info += "VPNChanged";
dialog_message(Dialog_DialogManageRoutes, info);
QDialog::accept();
}

View File

@@ -17,117 +17,227 @@
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="gridLayout_2">
<item row="1" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Outbound Domain Strategy</string>
</property>
</widget>
</item>
<item row="0" column="2">
<widget class="QComboBox" name="sniffing_mode">
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<property name="text">
<string>Disable</string>
</property>
</item>
<item>
<property name="text">
<string>The sniffing result is used for routing</string>
</property>
</item>
<item>
<property name="text">
<string>The sniffing result is used for destination</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Direct DNS</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Sniffing Mode</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>Remote DNS</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QComboBox" name="outbound_domain_strategy">
<property name="editable">
<bool>false</bool>
</property>
<item>
<property name="text">
<string notr="true">AsIs</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">UseIP</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">UseIPv4</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">UseIPv6</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">PreferIPv4</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">PreferIPv6</string>
</property>
</item>
</widget>
</item>
<item row="3" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLineEdit" name="dns_direct"/>
</item>
<item>
<widget class="QCheckBox" name="enhance_resolve_server_domain">
<property name="toolTip">
<string notr="true">使用多个境外 DNS 查询服务器地址,一定程度上可缓解对服务器域名的 DNS 污染,可能有副作用。</string>
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">增强域名解析</string>
<string>Sniffing Mode</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="sniffing_mode">
<item>
<property name="text">
<string>Disable</string>
</property>
</item>
<item>
<property name="text">
<string>The sniffing result is used for routing</string>
</property>
</item>
<item>
<property name="text">
<string>The sniffing result is used for destination</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="Line" name="line_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="label_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Outbound Domain Strategy</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="outbound_domain_strategy">
<property name="editable">
<bool>false</bool>
</property>
<item>
<property name="text">
<string notr="true">AsIs</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">UseIP</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">UseIPv4</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">UseIPv6</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">PreferIPv4</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">PreferIPv6</string>
</property>
</item>
</widget>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>VPN Implementation</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="vpn_implementation">
<item>
<property name="text">
<string notr="true">gVisor</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">System NAT</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">Tun2Socket</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QLabel" name="label_10">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">MTU</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="vpn_mtu">
<property name="editable">
<bool>true</bool>
</property>
<item>
<property name="text">
<string notr="true">9000</string>
</property>
</item>
<item>
<property name="text">
<string notr="true">1500</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QCheckBox" name="vpn_ipv6">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>VPN Enable IPv6</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="fake_dns">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string notr="true">FakeDNS</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="2">
<layout class="QHBoxLayout" name="horizontalLayout_5">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_9">
<property name="text">
<string>Remote DNS</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="dns_remote"/>
</item>
<item>
<widget class="QCheckBox" name="fake_dns">
<widget class="QLabel" name="label_8">
<property name="text">
<string notr="true">FakeDNS</string>
<string>Direct DNS</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="dns_direct"/>
</item>
<item>
<widget class="QCheckBox" name="enhance_resolve_server_domain">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string notr="true">使用多个境外 DNS 查询服务器地址,一定程度上可缓解对服务器域名的 DNS 污染,可能有副作用。</string>
</property>
<property name="text">
<string notr="true">增强域名解析</string>
</property>
</widget>
</item>
@@ -141,6 +251,12 @@
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="0,0,0,1,0,0">
<item>
<widget class="QCheckBox" name="dns_routing">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Enable DNS Routing</string>
</property>
@@ -344,8 +460,10 @@
<tabstops>
<tabstop>sniffing_mode</tabstop>
<tabstop>outbound_domain_strategy</tabstop>
<tabstop>dns_remote</tabstop>
<tabstop>vpn_implementation</tabstop>
<tabstop>vpn_mtu</tabstop>
<tabstop>fake_dns</tabstop>
<tabstop>dns_remote</tabstop>
<tabstop>dns_direct</tabstop>
<tabstop>enhance_resolve_server_domain</tabstop>
<tabstop>dns_routing</tabstop>
@@ -353,6 +471,8 @@
<tabstop>domainMatcherCombo</tabstop>
<tabstop>preset</tabstop>
<tabstop>custom_route_edit</tabstop>
<tabstop>custom_route_global_edit</tabstop>
<tabstop>load_save</tabstop>
</tabstops>
<resources/>
<connections>

View File

@@ -35,9 +35,6 @@
<property name="bottomMargin">
<number>0</number>
</property>
<property name="horizontalSpacing">
<number>0</number>
</property>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
@@ -92,9 +89,6 @@
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>

View File

@@ -472,10 +472,13 @@ void MainWindow::show_group(int gid) {
void MainWindow::dialog_message_impl(const QString &sender, const QString &info) {
if (info.contains("UpdateDataStore")) {
auto changed = NekoRay::dataStore->Save();
if (info.contains("RouteChanged")) changed = true;
refresh_proxy_list();
if (changed && NekoRay::dataStore->started_id >= 0 &&
QMessageBox::question(this, tr("Confirmation"), tr("Settings changed, restart proxy?")
) == QMessageBox::StandardButton::Yes) {
if (info.contains("VPNChanged") && title_spmode == NekoRay::SystemProxyMode::VPN) {
MessageBoxWarning(tr("VPN settings changed"), tr("Restart VPN to take effect."));
} else if (changed && NekoRay::dataStore->started_id >= 0 &&
QMessageBox::question(this, tr("Confirmation"), tr("Settings changed, restart proxy?")
) == QMessageBox::StandardButton::Yes) {
neko_start(NekoRay::dataStore->started_id);
}
refresh_status();
@@ -1336,7 +1339,10 @@ bool MainWindow::StartVPNProcess() {
#ifdef Q_OS_WIN
auto configFn = ":/nekoray/vpn/sing-box-vpn.json";
if (QFile::exists("vpn/sing-box-vpn.json")) configFn = "vpn/sing-box-vpn.json";
auto config = ReadFileText(configFn).replace("%PORT%", Int2String(NekoRay::dataStore->inbound_socks_port));
auto config = ReadFileText(configFn)
.replace("%IPV6_ADDRESS%", NekoRay::dataStore->vpn_ipv6 ? "\"inet6_address\": \"fdfe:dcba:9876::1/128\"," : "")
.replace("%MTU%", Int2String(NekoRay::dataStore->vpn_mtu))
.replace("%PORT%", Int2String(NekoRay::dataStore->inbound_socks_port));
#else
auto protectPath = QDir::currentPath() + "/protect";
auto configFn = ":/nekoray/vpn/vpn-run-root.sh";
@@ -1344,11 +1350,13 @@ bool MainWindow::StartVPNProcess() {
auto config = ReadFileText(configFn)
.replace("$PORT", Int2String(NekoRay::dataStore->inbound_socks_port))
.replace("$USE_NEKORAY", "1")
.replace("$ENABLE_IPV6", NekoRay::dataStore->vpn_ipv6 ? "1" : "")
.replace("./nekoray_core", QApplication::applicationDirPath() + "/nekoray_core")
.replace("./tun2socks", QApplication::applicationDirPath() + "/tun2socks")
.replace("$PROTECT_LISTEN_PATH", protectPath)
.replace("$TUN_NAME", "nekoray-tun")
.replace("$USER_ID", Int2String((int) getuid()))
.replace("$MTU", Int2String(NekoRay::dataStore->vpn_mtu))
.replace("$TABLE_FWMARK", "514");
#endif
//

View File

@@ -364,8 +364,8 @@ bool MainWindow::Tun2rayStartStop(bool start) {
if (start) {
libcore::SetTunReq req;
req.set_name("nekoray-tun");
req.set_mtu(1500);
req.set_implementation(0);
req.set_mtu(NekoRay::dataStore->vpn_mtu);
req.set_implementation(NekoRay::dataStore->vpn_implementation);
req.set_fakedns(NekoRay::dataStore->fake_dns);
auto error = defaultClient->SetTun(&ok, req);
if (!ok) return false;