GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( 96b8b3...22e1d6 )
by François
03:03
created

Firewall::getFirewall4()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 1
Metric Value
c 3
b 0
f 1
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
nop 3
1
<?php
2
/**
3
 * Copyright 2016 François Kooman <[email protected]>.
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 */
17
18
namespace fkooman\VPN\Server;
19
20
class Firewall
21
{
22
    public static function getFirewall4(Pools $p, $disableForward = false, $asArray = false)
23
    {
24
        return self::getFirewall($p, 4, $disableForward, $asArray);
25
    }
26
27
    public static function getFirewall6(Pools $p, $disableForward = false, $asArray = false)
28
    {
29
        return self::getFirewall($p, 6, $disableForward, $asArray);
30
    }
31
32
    private static function getFirewall(Pools $p, $inetFamily, $disableForward, $asArray)
33
    {
34
        $firewall = [];
35
36
        // NAT
37
        $firewall = array_merge($firewall, self::getNat($p, $inetFamily));
38
39
        // FILTER
40
        $firewall = array_merge($firewall, self::getFilter($p, $inetFamily, $disableForward));
41
42
        if ($asArray) {
43
            return $firewall;
44
        }
45
46
        return implode(PHP_EOL, $firewall).PHP_EOL;
47
    }
48
49
    private static function getNat(Pools $p, $inetFamily)
50
    {
51
        $nat = [
52
            '*nat',
53
            ':PREROUTING ACCEPT [0:0]',
54
            ':INPUT ACCEPT [0:0]',
55
            ':OUTPUT ACCEPT [0:0]',
56
            ':POSTROUTING ACCEPT [0:0]',
57
        ];
58
59
        foreach ($p as $pool) {
60
            if ($pool->getUseNat()) {
61
                if (4 === $inetFamily) {
62
                    // get the IPv4 range
63
                    $srcNet = $pool->getRange()->getAddressPrefix();
64
                } else {
65
                    // get the IPv6 range
66
                    $srcNet = $pool->getRange6()->getAddressPrefix();
67
                }
68
                $nat[] = sprintf('-A POSTROUTING -s %s -o %s -j MASQUERADE', $srcNet, $pool->getExtIf());
69
            }
70
        }
71
        $nat[] = 'COMMIT';
72
73
        return $nat;
74
    }
75
76
    private static function getFilter(Pools $p, $inetFamily, $disableForward)
77
    {
78
        $filter = [
79
            '*filter',
80
            ':INPUT ACCEPT [0:0]',
81
            ':FORWARD ACCEPT [0:0]',
82
            ':OUTPUT ACCEPT [0:0]',
83
        ];
84
85
        // INPUT
86
        $filter = array_merge($filter, self::getInputChain($p, $inetFamily));
87
88
        // FORWARD
89
        $filter = array_merge($filter, self::getForwardChain($p, $inetFamily, $disableForward));
90
91
        $filter[] = 'COMMIT';
92
93
        return $filter;
94
    }
95
96
    private static function getInputChain(Pools $p, $inetFamily)
97
    {
98
        $inputChain = [
99
            '-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT',
100
            sprintf('-A INPUT -p %s -j ACCEPT', 4 === $inetFamily ? 'icmp' : 'ipv6-icmp'),
101
            '-A INPUT -i lo -j ACCEPT',
102
        ];
103
104
        $inputPorts = self::getIngressPorts($p);
105
        foreach ($inputPorts as $inputPort) {
106
            list($proto, $port) = explode('/', $inputPort);
107
            $inputChain[] = sprintf('-A INPUT -m state --state NEW -m %s -p %s --dport %d -j ACCEPT', $proto, $proto, $port);
108
        }
109
110
        $inputChain[] = sprintf('-A INPUT -j REJECT --reject-with %s', 4 === $inetFamily ? 'icmp-host-prohibited' : 'icmp6-adm-prohibited');
111
112
        return $inputChain;
113
    }
114
115
    private static function getForwardChain(Pools $p, $inetFamily, $disableForward)
116
    {
117
        $forwardChain = [
118
            '-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT',
119
        ];
120
121
        if (!$disableForward) {
122
            foreach ($p as $pool) {
123
                if (4 === $inetFamily) {
124
                    // get the IPv4 range
125
                    $srcNet = $pool->getRange()->getAddressPrefix();
126
                } else {
127
                    // get the IPv6 range
128
                    $srcNet = $pool->getRange6()->getAddressPrefix();
129
                }
130
                $forwardChain[] = sprintf('-N vpn-%s', $pool->getId());
131
                $forwardChain[] = sprintf('-A FORWARD -i tun-%s+ -s %s -j vpn-%s', $pool->getId(), $srcNet, $pool->getId());
132
                if ($pool->getClientToClient()) {
133
                    // allow client-to-client
134
                    $forwardChain[] = sprintf('-A vpn-%s -o tun-%s+ -d %s -j ACCEPT', $pool->getId(), $pool->getId(), $srcNet);
135
                }
136
                if ($pool->getDefaultGateway()) {
137
                    // allow all traffic to the external interface
138
139
                    // drop netbios
140
                    // @see https://medium.com/@ValdikSS/deanonymizing-windows-users-and-capturing-microsoft-and-vpn-accounts-f7e53fe73834
141
                    foreach (['tcp', 'udp'] as $proto) {
142
                        $forwardChain[] = sprintf(
143
                            '-A vpn-%s -o %s -m multiport -p %s --dports 137:139,445 -j REJECT --reject-with %s',
144
                            $pool->getId(),
145
                            $pool->getExtIf(),
146
                            $proto,
147
                            4 === $inetFamily ? 'icmp-host-prohibited' : 'icmp6-adm-prohibited');
148
                    }
149
150
                    $forwardChain[] = sprintf('-A vpn-%s -o %s -j ACCEPT', $pool->getId(), $pool->getExtIf(), $srcNet);
151
                } else {
152
                    // only allow certain traffic to the external interface
153
                    foreach ($pool->getRoutes() as $route) {
154
                        if ($inetFamily === $route->getFamily()) {
155
                            $forwardChain[] = sprintf('-A vpn-%s -o %s -d %s -j ACCEPT', $pool->getId(), $pool->getExtIf(), $route->getAddressPrefix());
156
                        }
157
                    }
158
                }
159
            }
160
        }
161
162
        $forwardChain[] = sprintf('-A FORWARD -j REJECT --reject-with %s', 4 === $inetFamily ? 'icmp-host-prohibited' : 'icmp6-adm-prohibited');
163
164
        return $forwardChain;
165
    }
166
167
    private static function getIngressPorts(Pools $p)
168
    {
169
        $ingressPorts = ['tcp/22', 'tcp/80', 'tcp/443'];
170
171
        // we only care about additional UDP ports, as we only want UDP and
172
        // fallback to tcp/443
173
        foreach ($p as $pool) {
174
            foreach ($pool->getInstances() as $instance) {
175
                if ('udp' === $instance->getProto()) {
176
                    $port = sprintf('udp/%d', $instance->getPort());
177
                    if (!in_array($port, $ingressPorts)) {
178
                        $ingressPorts[] = $port;
179
                    }
180
                }
181
            }
182
        }
183
184
        return $ingressPorts;
185
    }
186
}
187