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 ( 3d13d3...70079c )
by François
02:40
created

Firewall::getFirewall4()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 3
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 *  Copyright (C) 2016 SURFnet.
4
 *
5
 *  This program is free software: you can redistribute it and/or modify
6
 *  it under the terms of the GNU Affero General Public License as
7
 *  published by the Free Software Foundation, either version 3 of the
8
 *  License, or (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU Affero General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU Affero General Public License
16
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
 */
18
namespace SURFnet\VPN\Server\Config;
19
20
use SURFnet\VPN\Common\Config;
21
use SURFnet\VPN\Server\PoolConfig;
22
use SURFnet\VPN\Server\FirewallConfig;
23
use SURFnet\VPN\Server\IP;
24
25
class Firewall
26
{
27
    public static function getFirewall4(array $configList, FirewallConfig $firewallConfig, $asArray = false)
28
    {
29
        return self::getFirewall($configList, $firewallConfig, 4, $asArray);
30
    }
31
32
    public static function getFirewall6(array $configList, FirewallConfig $firewallConfig, $asArray = false)
33
    {
34
        return self::getFirewall($configList, $firewallConfig, 6, $asArray);
35
    }
36
37
    private static function getFirewall(array $configList, FirewallConfig $firewallConfig, $inetFamily, $asArray)
38
    {
39
        $firewall = [];
40
41
        // NAT
42
        $firewall = array_merge(
43
            $firewall,
44
             [
45
            '*nat',
46
            ':PREROUTING ACCEPT [0:0]',
47
            ':INPUT ACCEPT [0:0]',
48
            ':OUTPUT ACCEPT [0:0]',
49
            ':POSTROUTING ACCEPT [0:0]',
50
            ]
51
        );
52
        // add all instances
53
        foreach ($configList as $config) {
54
            $firewall = array_merge($firewall, self::getNat($config, $inetFamily));
55
        }
56
        $firewall[] = 'COMMIT';
57
58
        // FILTER
59
        $firewall = array_merge(
60
            $firewall,
61
            [
62
                '*filter',
63
                ':INPUT ACCEPT [0:0]',
64
                ':FORWARD ACCEPT [0:0]',
65
                ':OUTPUT ACCEPT [0:0]',
66
            ]
67
        );
68
69
        // INPUT
70
        $firewall = array_merge($firewall, self::getInputChain($inetFamily, $firewallConfig));
71
72
        // FORWARD
73
        $firewall = array_merge(
74
            $firewall,
75
            [
76
                //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...
77
                '-A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT',
78
            ]
79
        );
80
81
        // add all instances
82
        foreach ($configList as $config) {
83
            $firewall = array_merge($firewall, self::getForwardChain($config, $inetFamily));
84
        }
85
        $firewall[] = sprintf('-A FORWARD -j REJECT --reject-with %s', 4 === $inetFamily ? 'icmp-host-prohibited' : 'icmp6-adm-prohibited');
86
        $firewall[] = 'COMMIT';
87
88
        if ($asArray) {
89
            return $firewall;
90
        }
91
92
        return implode(PHP_EOL, $firewall).PHP_EOL;
93
    }
94
95
    private static function getNat(Config $config, $inetFamily)
96
    {
97
        $nat = [];
98
99
        foreach (array_keys($config->v('vpnPools')) as $poolId) {
100
            $poolConfig = new PoolConfig($config->v('vpnPools', $poolId));
101
            if ($poolConfig->v('useNat')) {
102
                if (4 === $inetFamily) {
103
                    // get the IPv4 range
104
                    $srcNet = $poolConfig->v('range');
105
                } else {
106
                    // get the IPv6 range
107
                    $srcNet = $poolConfig->v('range6');
108
                }
109
                // -i (--in-interface) cannot be specified for POSTROUTING
110
                $nat[] = sprintf('-A POSTROUTING -s %s -o %s -j MASQUERADE', $srcNet, $poolConfig->v('extIf'));
111
            }
112
        }
113
114
        return $nat;
115
    }
116
117
    private static function getInputChain($inetFamily, FirewallConfig $firewallConfig)
118
    {
119
        $inputChain = [
120
            '-A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT',
121
            sprintf('-A INPUT -p %s -j ACCEPT', 4 === $inetFamily ? 'icmp' : 'ipv6-icmp'),
122
            '-A INPUT -i lo -j ACCEPT',
123
        ];
124
125
        $inputChain[] = sprintf(
126
            '-A INPUT -m state --state NEW -m multiport -p udp --dports %s -j ACCEPT',
127
            implode(',', $firewallConfig->v('inputChain', 'udp'))
128
        );
129
130
        $inputChain[] = sprintf(
131
            '-A INPUT -m state --state NEW -m multiport -p tcp --dports %s -j ACCEPT',
132
            implode(',', $firewallConfig->v('inputChain', 'tcp'))
133
        );
134
135
//        foreach($firewallConfig->v('inputChain', 'udp') as $entry) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% 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...
136
//            $inputChain[] = sprintf('-A INPUT -m state --state NEW -m udp -p udp --dport %s -j ACCEPT', $entry);
137
//        }
138
139
//        foreach($firewallConfig->v('inputChain', 'tcp') as $entry) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
61% 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...
140
//            $inputChain[] = sprintf('-A INPUT -m state --state NEW -m tcp -p tcp --dport %s -j ACCEPT', $entry);
141
//        }
142
143
//            '-A INPUT -m state --state NEW -m multiport -p tcp --dports 22,80,443 -j ACCEPT',
0 ignored issues
show
Unused Code Comprehensibility introduced by
58% 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...
144
//            '-A INPUT -m state --state NEW -m udp -p udp --dport 1194:1201 -j ACCEPT',
145
146
        $inputChain[] = sprintf('-A INPUT -j REJECT --reject-with %s', 4 === $inetFamily ? 'icmp-host-prohibited' : 'icmp6-adm-prohibited');
147
148
        return $inputChain;
149
    }
150
151
    private static function getForwardChain(Config $config, $inetFamily)
152
    {
153
        $forwardChain = [];
154
155
        foreach (array_keys($config->v('vpnPools')) as $poolId) {
156
            $poolConfig = new PoolConfig($config->v('vpnPools', $poolId));
157
            $poolNumber = $poolConfig->v('poolNumber');
158
            if (6 === $inetFamily && !$poolConfig->v('forward6')) {
159
                // IPv6 forwarding was disabled
160
                continue;
161
            }
162
163
            if (4 === $inetFamily) {
164
                // get the IPv4 range
165
                $srcNet = $poolConfig->v('range');
166
            } else {
167
                // get the IPv6 range
168
                $srcNet = $poolConfig->v('range6');
169
            }
170
            $forwardChain[] = sprintf('-N vpn-%s-%s', $config->v('instanceNumber'), $poolNumber);
171
172
            $forwardChain[] = sprintf('-A FORWARD -i tun-%s-%s+ -s %s -j vpn-%s-%s', $config->v('instanceNumber'), $poolNumber, $srcNet, $config->v('instanceNumber'), $poolNumber);
173
174
            // merge outgoing forwarding firewall rules to prevent certain
175
            // traffic
176
            $forwardChain = array_merge($forwardChain, self::getForwardFirewall($config->v('instanceNumber'), $poolNumber, $poolConfig, $inetFamily));
177
178
            if ($poolConfig->v('clientToClient')) {
179
                // allow client-to-client
180
                $forwardChain[] = sprintf('-A vpn-%s-%s -o tun-%s-%s+ -d %s -j ACCEPT', $config->v('instanceNumber'), $poolNumber, $config->v('instanceNumber'), $poolNumber, $srcNet);
181
            }
182
            if ($poolConfig->v('defaultGateway')) {
183
                // allow traffic to all outgoing destinations
184
                $forwardChain[] = sprintf('-A vpn-%s-%s -o %s -j ACCEPT', $config->v('instanceNumber'), $poolNumber, $poolConfig->v('extIf'), $srcNet);
185
            } else {
186
                // only allow certain traffic to the external interface
187
                foreach ($poolConfig->v('routes') as $route) {
188
                    $routeIp = new IP($route);
189
                    if ($inetFamily === $routeIp->getFamily()) {
190
                        $forwardChain[] = sprintf('-A vpn-%s-%s -o %s -d %s -j ACCEPT', $config->v('instanceNumber'), $poolNumber, $poolConfig->v('extIf'), $route);
191
                    }
192
                }
193
            }
194
        }
195
196
        return $forwardChain;
197
    }
198
199
    private static function getForwardFirewall($instanceNumber, $poolNumber, PoolConfig $poolConfig, $inetFamily)
200
    {
201
        $forwardFirewall = [];
202
        if ($poolConfig->v('blockSmb')) {
203
            // drop SMB outgoing traffic
204
            // @see https://medium.com/@ValdikSS/deanonymizing-windows-users-and-capturing-microsoft-and-vpn-accounts-f7e53fe73834
205
            foreach (['tcp', 'udp'] as $proto) {
206
                $forwardFirewall[] = sprintf(
207
                    '-A vpn-%s-%s -o %s -m multiport -p %s --dports 137:139,445 -j REJECT --reject-with %s',
208
                    $instanceNumber,
209
                    $poolNumber,
210
                    $poolConfig->v('extIf'),
211
                    $proto,
212
                    4 === $inetFamily ? 'icmp-host-prohibited' : 'icmp6-adm-prohibited');
213
            }
214
        }
215
216
        return $forwardFirewall;
217
    }
218
}
219