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 ( d122ce...eff07b )
by François
03:18
created

Firewall::getFirewall()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 57
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 1 Features 1
Metric Value
c 5
b 1
f 1
dl 0
loc 57
rs 8.7433
cc 5
eloc 29
nc 8
nop 3

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
namespace fkooman\VPN\Server;
18
19
class Firewall
20
{
21
    public static function getFirewall4(array $instanceList, $asArray = false)
22
    {
23
        return self::getFirewall($instanceList, 4, $asArray);
24
    }
25
26
    public static function getFirewall6(array $instanceList, $asArray = false)
27
    {
28
        return self::getFirewall($instanceList, 6, $asArray);
29
    }
30
31
    private static function getFirewall(array $instanceList, $inetFamily, $asArray)
32
    {
33
        $firewall = [];
34
35
        // NAT
36
        $firewall = array_merge(
37
            $firewall,
38
             [
39
            '*nat',
40
            ':PREROUTING ACCEPT [0:0]',
41
            ':INPUT ACCEPT [0:0]',
42
            ':OUTPUT ACCEPT [0:0]',
43
            ':POSTROUTING ACCEPT [0:0]',
44
            ]
45
        );
46
        // add all instances
47
        foreach ($instanceList as $instanceId => $p) {
48
            $firewall = array_merge($firewall, self::getNat($p, $inetFamily));
49
        }
50
        $firewall[] = 'COMMIT';
51
52
        // FILTER
53
        $firewall = array_merge(
54
            $firewall,
55
            [
56
                '*filter',
57
                ':INPUT ACCEPT [0:0]',
58
                ':FORWARD ACCEPT [0:0]',
59
                ':OUTPUT ACCEPT [0:0]',
60
            ]
61
        );
62
63
        // INPUT
64
        $firewall = array_merge($firewall, self::getInputChain($inetFamily));
65
66
        // FORWARD
67
        $firewall = array_merge(
68
            $firewall,
69
            [
70
                //sprintf('-A FORWARD -p %s -j ACCEPT', 4 === $inetFamily ? 'icmp' : 'ipv6-icmp'),
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
71
                '-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT',
72
            ]
73
        );
74
75
        // add all instances
76
        foreach ($instanceList as $instanceId => $p) {
77
            $firewall = array_merge($firewall, self::getForwardChain($instanceId, $p, $inetFamily));
78
        }
79
        $firewall[] = sprintf('-A FORWARD -j REJECT --reject-with %s', 4 === $inetFamily ? 'icmp-host-prohibited' : 'icmp6-adm-prohibited');
80
        $firewall[] = 'COMMIT';
81
82
        if ($asArray) {
83
            return $firewall;
84
        }
85
86
        return implode(PHP_EOL, $firewall).PHP_EOL;
87
    }
88
89
    private static function getNat(Pools $p, $inetFamily)
90
    {
91
        $nat = [];
92
93
        foreach ($p as $pool) {
94
            if ($pool->getUseNat()) {
95
                if (4 === $inetFamily) {
96
                    // get the IPv4 range
97
                    $srcNet = $pool->getRange()->getAddressPrefix();
98
                } else {
99
                    // get the IPv6 range
100
                    $srcNet = $pool->getRange6()->getAddressPrefix();
101
                }
102
                // -i (--in-interface) cannot be specified for POSTROUTING
103
                $nat[] = sprintf('-A POSTROUTING -s %s -o %s -j MASQUERADE', $srcNet, $pool->getExtIf());
104
            }
105
        }
106
107
        return $nat;
108
    }
109
110
    private static function getInputChain($inetFamily)
111
    {
112
        $inputChain = [
113
            '-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT',
114
            sprintf('-A INPUT -p %s -j ACCEPT', 4 === $inetFamily ? 'icmp' : 'ipv6-icmp'),
115
            '-A INPUT -i lo -j ACCEPT',
116
            '-A INPUT -m state --state NEW -m multiport -p tcp --dports 22,80,443 -j ACCEPT',
117
            '-A INPUT -m state --state NEW -m udp -p udp --dport 1194:1201 -j ACCEPT',
118
            sprintf('-A INPUT -j REJECT --reject-with %s', 4 === $inetFamily ? 'icmp-host-prohibited' : 'icmp6-adm-prohibited'),
119
        ];
120
121
        return $inputChain;
122
    }
123
124
    private static function getForwardChain($instanceId, Pools $p, $inetFamily)
125
    {
126
        $forwardChain = [];
127
128
        foreach ($p as $pool) {
129
            if (6 === $inetFamily && !$pool->getForward6()) {
130
                // IPv6 forwarding was disabled
131
                continue;
132
            }
133
134
            if (4 === $inetFamily) {
135
                // get the IPv4 range
136
                $srcNet = $pool->getRange()->getAddressPrefix();
137
            } else {
138
                // get the IPv6 range
139
                $srcNet = $pool->getRange6()->getAddressPrefix();
140
            }
141
            $forwardChain[] = sprintf('-N vpn-%s-%s', $instanceId, $pool->getId());
142
143
            $forwardChain[] = sprintf('-A FORWARD -i tun-%s-%s+ -s %s -j vpn-%s-%s', $instanceId, $pool->getId(), $srcNet, $instanceId, $pool->getId());
144
145
            // merge outgoing forwarding firewall rules to prevent certain
146
            // traffic
147
            $forwardChain = array_merge($forwardChain, self::getForwardFirewall($instanceId, $pool, $inetFamily));
148
149
            if ($pool->getClientToClient()) {
150
                // allow client-to-client
151
                $forwardChain[] = sprintf('-A vpn-%s-%s -o tun-%s-%s+ -d %s -j ACCEPT', $instanceId, $pool->getId(), $instanceId, $pool->getId(), $srcNet);
152
            }
153
            if ($pool->getDefaultGateway()) {
154
                // allow traffic to all outgoing destinations
155
                $forwardChain[] = sprintf('-A vpn-%s-%s -o %s -j ACCEPT', $instanceId, $pool->getId(), $pool->getExtIf(), $srcNet);
156
            } else {
157
                // only allow certain traffic to the external interface
158
                foreach ($pool->getRoutes() as $route) {
159
                    if ($inetFamily === $route->getFamily()) {
160
                        $forwardChain[] = sprintf('-A vpn-%s-%s -o %s -d %s -j ACCEPT', $instanceId, $pool->getId(), $pool->getExtIf(), $route->getAddressPrefix());
161
                    }
162
                }
163
            }
164
        }
165
166
        return $forwardChain;
167
    }
168
169
    private static function getForwardFirewall($instanceId, Pool $pool, $inetFamily)
170
    {
171
        $forwardFirewall = [];
172
173
        if ($pool->getBlockSmb()) {
174
            // drop SMB outgoing traffic
175
            // @see https://medium.com/@ValdikSS/deanonymizing-windows-users-and-capturing-microsoft-and-vpn-accounts-f7e53fe73834
176
            foreach (['tcp', 'udp'] as $proto) {
177
                $forwardFirewall[] = sprintf(
178
                    '-A vpn-%s-%s -o %s -m multiport -p %s --dports 137:139,445 -j REJECT --reject-with %s',
179
                    $instanceId,
180
                    $pool->getId(),
181
                    $pool->getExtIf(),
182
                    $proto,
183
                    4 === $inetFamily ? 'icmp-host-prohibited' : 'icmp6-adm-prohibited');
184
            }
185
        }
186
187
        return $forwardFirewall;
188
    }
189
}
190