Setup MTU for AWG/WG protocol

This commit is contained in:
Mykola Baibuz
2024-02-10 15:38:03 +02:00
parent dba05aab07
commit 26b8444480
17 changed files with 243 additions and 18 deletions
@@ -41,6 +41,8 @@ QString AwgConfigurator::genAwgConfig(const ServerCredentials &credentials, Dock
jsonConfig[config_key::responsePacketMagicHeader] = configMap.value(config_key::responsePacketMagicHeader);
jsonConfig[config_key::underloadPacketMagicHeader] = configMap.value(config_key::underloadPacketMagicHeader);
jsonConfig[config_key::transportPacketMagicHeader] = configMap.value(config_key::transportPacketMagicHeader);
jsonConfig[config_key::mtu] = containerConfig.value(ProtocolProps::protoToString(Proto::Awg)).toObject().
value(config_key::mtu).toString(protocols::awg::defaultMtu);
return QJsonDocument(jsonConfig).toJson();
}
@@ -194,6 +194,7 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
config.replace("$WIREGUARD_SERVER_PUBLIC_KEY", connData.serverPubKey);
config.replace("$WIREGUARD_PSK", connData.pskKey);
const QJsonObject &wireguarConfig = containerConfig.value(ProtocolProps::protoToString(Proto::WireGuard)).toObject();
QJsonObject jConfig;
jConfig[config_key::config] = config;
@@ -205,6 +206,8 @@ QString WireguardConfigurator::genWireguardConfig(const ServerCredentials &crede
jConfig[config_key::psk_key] = connData.pskKey;
jConfig[config_key::server_pub_key] = connData.serverPubKey;
jConfig[config_key::mtu] = wireguarConfig.value(config_key::mtu).toString(protocols::wireguard::defaultMtu);
clientId = connData.clientPubKey;
return QJsonDocument(jConfig).toJson();
+7
View File
@@ -251,6 +251,13 @@ bool Daemon::parseConfig(const QJsonObject& obj, InterfaceConfig& config) {
GETVALUE("serverPskKey", config.m_serverPskKey, String);
GETVALUE("serverPort", config.m_serverPort, Double);
if (!obj.contains("deviceMTU") || obj.value("deviceMTU").toString().toInt() == 0)
{
config.m_deviceMTU = 1420;
} else {
config.m_deviceMTU = obj.value("deviceMTU").toString().toInt();
}
config.m_deviceIpv4Address = obj.value("deviceIpv4Address").toString();
config.m_deviceIpv6Address = obj.value("deviceIpv6Address").toString();
if (config.m_deviceIpv4Address.isNull() &&
+6
View File
@@ -23,6 +23,7 @@ QJsonObject InterfaceConfig::toJson() const {
json.insert("serverIpv4AddrIn", QJsonValue(m_serverIpv4AddrIn));
json.insert("serverIpv6AddrIn", QJsonValue(m_serverIpv6AddrIn));
json.insert("serverPort", QJsonValue((double)m_serverPort));
json.insert("deviceMTU", QJsonValue(m_deviceMTU));
if ((m_hopType == InterfaceConfig::MultiHopExit) ||
(m_hopType == InterfaceConfig::SingleHop)) {
json.insert("serverIpv4Gateway", QJsonValue(m_serverIpv4Gateway));
@@ -85,8 +86,13 @@ QString InterfaceConfig::toWgConf(const QMap<QString, QString>& extra) const {
if (addresses.isEmpty()) {
return "";
}
out << "Address = " << addresses.join(", ") << "\n";
if (!m_deviceMTU) {
out << "MTU = " << m_deviceMTU << "\n";
}
if (!m_dnsServer.isNull()) {
QStringList dnsServers(m_dnsServer);
// If the DNS is not the Gateway, it's a user defined DNS
+1
View File
@@ -33,6 +33,7 @@ class InterfaceConfig {
QString m_serverIpv6AddrIn;
QString m_dnsServer;
int m_serverPort = 0;
int m_deviceMTU = 1420;
QList<IPAddress> m_allowedIPAddressRanges;
QStringList m_excludedAddresses;
QStringList m_vpnDisabledApps;
+2 -1
View File
@@ -133,8 +133,9 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
json.insert("serverPskKey", wgConfig.value(amnezia::config_key::psk_key));
json.insert("serverIpv4AddrIn", wgConfig.value(amnezia::config_key::hostName));
// json.insert("serverIpv6AddrIn", QJsonValue(hop.m_server.ipv6AddrIn()));
json.insert("serverPort", wgConfig.value(amnezia::config_key::port).toInt());
json.insert("deviceMTU", wgConfig.value(amnezia::config_key::mtu));
json.insert("serverPort", wgConfig.value(amnezia::config_key::port).toInt());
json.insert("serverIpv4Gateway", wgConfig.value(amnezia::config_key::hostName));
// json.insert("serverIpv6Gateway", QJsonValue(hop.m_server.ipv6Gateway()));
json.insert("dnsServer", rawConfig.value(amnezia::config_key::dns1));
@@ -38,8 +38,6 @@ bool IPUtilsLinux::addInterfaceIPs(const InterfaceConfig& config) {
}
bool IPUtilsLinux::setMTUAndUp(const InterfaceConfig& config) {
Q_UNUSED(config);
// Create socket file descriptor to perform the ioctl operations on
int sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
if (sockfd < 0) {
@@ -56,10 +54,10 @@ bool IPUtilsLinux::setMTUAndUp(const InterfaceConfig& config) {
// FIXME: We need to know how many layers deep this particular
// interface is into a tunnel to work effectively. Otherwise
// we will run into fragmentation issues.
ifr.ifr_mtu = ETH_MTU - WG_MTU_OVERHEAD;
ifr.ifr_mtu = config.m_deviceMTU;
int ret = ioctl(sockfd, SIOCSIFMTU, &ifr);
if (ret) {
logger.error() << "Failed to set MTU -- Return code: " << ret;
logger.error() << "Failed to set MTU -- " << config.m_deviceMTU << " -- Return code: " << ret;
return false;
}
+3
View File
@@ -44,6 +44,7 @@ namespace amnezia
constexpr char server_priv_key[] = "server_priv_key";
constexpr char server_pub_key[] = "server_pub_key";
constexpr char psk_key[] = "psk_key";
constexpr char mtu[] = "mtu";
constexpr char allowed_ips[] = "allowed_ips";
constexpr char client_ip[] = "client_ip"; // internal ip address
@@ -146,6 +147,7 @@ namespace amnezia
constexpr char defaultSubnetCidr[] = "24";
constexpr char defaultPort[] = "51820";
constexpr char defaultMtu[] = "1420";
constexpr char serverConfigPath[] = "/opt/amnezia/wireguard/wg0.conf";
constexpr char serverPublicKeyPath[] = "/opt/amnezia/wireguard/wireguard_server_public_key.key";
constexpr char serverPskKeyPath[] = "/opt/amnezia/wireguard/wireguard_psk.key";
@@ -161,6 +163,7 @@ namespace amnezia
namespace awg
{
constexpr char defaultPort[] = "55424";
constexpr char defaultMtu[] = "1420";
constexpr char serverConfigPath[] = "/opt/amnezia/awg/wg0.conf";
constexpr char serverPublicKeyPath[] = "/opt/amnezia/awg/wireguard_server_public_key.key";
+1
View File
@@ -225,5 +225,6 @@
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
<file>images/controls/close.svg</file>
<file>images/controls/search.svg</file>
<file>ui/qml/Pages2/PageProtocolWireGuardSettings.qml</file>
</qresource>
</RCC>
@@ -252,6 +252,10 @@ QJsonObject ImportController::extractWireGuardConfig(const QString &data)
// return QJsonObject();
// }
if (!configMap.value("MTU").isEmpty()) {
lastConfig[config_key::mtu] = configMap.value("MTU");
}
QJsonArray allowedIpsJsonArray = QJsonArray::fromStringList(configMap.value("AllowedIPs").split(","));
lastConfig[config_key::allowed_ips] = allowedIpsJsonArray;
@@ -22,6 +22,7 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in
switch (role) {
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
case Roles::MtuRole: m_protocolConfig.insert(config_key::mtu, value.toString()); break;
case Roles::JunkPacketCountRole: m_protocolConfig.insert(config_key::junkPacketCount, value.toString()); break;
case Roles::JunkPacketMinSizeRole: m_protocolConfig.insert(config_key::junkPacketMinSize, value.toString()); break;
case Roles::JunkPacketMaxSizeRole: m_protocolConfig.insert(config_key::junkPacketMaxSize, value.toString()); break;
@@ -57,6 +58,7 @@ QVariant AwgConfigModel::data(const QModelIndex &index, int role) const
switch (role) {
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString();
case Roles::MtuRole: return m_protocolConfig.value(config_key::mtu).toString();
case Roles::JunkPacketCountRole: return m_protocolConfig.value(config_key::junkPacketCount);
case Roles::JunkPacketMinSizeRole: return m_protocolConfig.value(config_key::junkPacketMinSize);
case Roles::JunkPacketMaxSizeRole: return m_protocolConfig.value(config_key::junkPacketMaxSize);
@@ -82,6 +84,8 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
m_protocolConfig[config_key::port] =
protocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
m_protocolConfig[config_key::mtu] =
protocolConfig.value(config_key::mtu).toString(protocols::awg::defaultMtu);
m_protocolConfig[config_key::junkPacketCount] =
protocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
m_protocolConfig[config_key::junkPacketMinSize] =
@@ -123,6 +127,7 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
QHash<int, QByteArray> roles;
roles[PortRole] = "port";
roles[MtuRole] = "mtu";
roles[JunkPacketCountRole] = "junkPacketCount";
roles[JunkPacketMinSizeRole] = "junkPacketMinSize";
roles[JunkPacketMaxSizeRole] = "junkPacketMaxSize";
@@ -13,6 +13,7 @@ class AwgConfigModel : public QAbstractListModel
public:
enum Roles {
PortRole = Qt::UserRole + 1,
MtuRole,
JunkPacketCountRole,
JunkPacketMinSizeRole,
JunkPacketMaxSizeRole,
@@ -19,8 +19,8 @@ bool WireGuardConfigModel::setData(const QModelIndex &index, const QVariant &val
}
switch (role) {
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
case Roles::CipherRole: m_protocolConfig.insert(config_key::cipher, value.toString()); break;
case Roles::PortRole: m_protocolConfig.insert(config_key::port, value.toString()); break;
case Roles::MtuRole: m_protocolConfig.insert(config_key::mtu, value.toString()); break;
}
emit dataChanged(index, index, QList { role });
@@ -34,9 +34,8 @@ QVariant WireGuardConfigModel::data(const QModelIndex &index, int role) const
}
switch (role) {
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString(protocols::shadowsocks::defaultPort);
case Roles::CipherRole:
return m_protocolConfig.value(config_key::cipher).toString(protocols::shadowsocks::defaultCipher);
case Roles::PortRole: return m_protocolConfig.value(config_key::port).toString();
case Roles::MtuRole: return m_protocolConfig.value(config_key::mtu).toString();
}
return QVariant();
@@ -50,6 +49,12 @@ void WireGuardConfigModel::updateModel(const QJsonObject &config)
m_fullConfig = config;
QJsonObject protocolConfig = config.value(config_key::wireguard).toObject();
m_protocolConfig[config_key::port] =
protocolConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
m_protocolConfig[config_key::mtu] =
protocolConfig.value(config_key::mtu).toString(protocols::wireguard::defaultMtu);
endResetModel();
}
@@ -64,7 +69,7 @@ QHash<int, QByteArray> WireGuardConfigModel::roleNames() const
QHash<int, QByteArray> roles;
roles[PortRole] = "port";
roles[CipherRole] = "cipher";
roles[MtuRole] = "mtu";
return roles;
}
@@ -13,7 +13,7 @@ class WireGuardConfigModel : public QAbstractListModel
public:
enum Roles {
PortRole = Qt::UserRole + 1,
CipherRole
MtuRole
};
explicit WireGuardConfigModel(QObject *parent = nullptr);
@@ -58,10 +58,8 @@ ListView {
break
}
case ContainerEnum.WireGuard: {
ProtocolsModel.updateModel(config)
PageController.goToPage(PageEnum.PageProtocolRaw)
// WireGuardConfigModel.updateModel(config)
// goToPage(PageEnum.PageProtocolWireGuardSettings)
WireGuardConfigModel.updateModel(config)
PageController.goToPage(PageEnum.PageProtocolWireGuardSettings)
break
}
case ContainerEnum.Awg: {
@@ -72,8 +70,6 @@ ListView {
case ContainerEnum.Ipsec: {
ProtocolsModel.updateModel(config)
PageController.goToPage(PageEnum.PageProtocolRaw)
// Ikev2ConfigModel.updateModel(config)
// goToPage(PageEnum.PageProtocolIKev2Settings)
break
}
case ContainerEnum.Sftp: {
@@ -95,6 +95,26 @@ PageType {
checkEmptyText: true
}
TextFieldWithHeaderType {
id: mtuTextField
Layout.fillWidth: true
Layout.topMargin: 16
headerText: qsTr("MTU")
textFieldText: mtu
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText === "") {
textFieldText = "0"
}
if (textFieldText !== mtu) {
mtu = textFieldText
}
}
checkEmptyText: true
}
TextFieldWithHeaderType {
id: junkPacketCountTextField
Layout.fillWidth: true
@@ -0,0 +1,172 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import SortFilterProxyModel 0.2
import PageEnum 1.0
import "./"
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
import "../Components"
PageType {
id: root
ColumnLayout {
id: backButton
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 20
BackButtonType {
}
}
FlickableType {
id: fl
anchors.top: backButton.bottom
anchors.bottom: parent.bottom
contentHeight: content.implicitHeight
Column {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
ListView {
id: listview
width: parent.width
height: listview.contentItem.height
clip: true
interactive: false
model: WireGuardConfigModel
delegate: Item {
implicitWidth: listview.width
implicitHeight: col.implicitHeight
ColumnLayout {
id: col
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.rightMargin: 16
spacing: 0
HeaderType {
Layout.fillWidth: true
headerText: qsTr("WG settings")
}
TextFieldWithHeaderType {
id: portTextField
Layout.fillWidth: true
Layout.topMargin: 40
headerText: qsTr("Port")
textFieldText: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
textField.onEditingFinished: {
if (textFieldText !== port) {
port = textFieldText
}
}
checkEmptyText: true
}
TextFieldWithHeaderType {
id: mtuTextField
Layout.fillWidth: true
Layout.topMargin: 16
headerText: qsTr("MTU")
textFieldText: mtu
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText === "") {
textFieldText = "0"
}
if (textFieldText !== mtu) {
mtu = textFieldText
}
}
checkEmptyText: true
}
BasicButtonType {
Layout.topMargin: 24
Layout.leftMargin: -8
implicitHeight: 32
defaultColor: "transparent"
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
pressedColor: Qt.rgba(1, 1, 1, 0.12)
textColor: "#EB5757"
text: qsTr("Remove WG")
onClicked: {
questionDrawer.headerText = qsTr("Remove WG from server?")
questionDrawer.descriptionText = qsTr("All users with whom you shared a connection will no longer be able to connect to it.")
questionDrawer.yesButtonText = qsTr("Continue")
questionDrawer.noButtonText = qsTr("Cancel")
questionDrawer.yesButtonFunction = function() {
questionDrawer.visible = false
PageController.goToPage(PageEnum.PageDeinstalling)
InstallController.removeCurrentlyProcessedContainer()
}
questionDrawer.noButtonFunction = function() {
questionDrawer.visible = false
}
questionDrawer.visible = true
}
}
BasicButtonType {
Layout.fillWidth: true
Layout.topMargin: 24
Layout.bottomMargin: 24
enabled: mtuTextField.errorText === "" &&
portTextField.errorText === ""
text: qsTr("Save and Restart Amnezia")
onClicked: {
forceActiveFocus()
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
InstallController.updateContainer(WireGuardConfigModel.getConfig())
}
}
}
}
}
}
QuestionDrawer {
id: questionDrawer
}
}
}