mirror of
https://github.com/trailofbits/algo.git
synced 2025-09-06 12:03:38 +02:00
Merge branch 'master' into add-faq-entry-disable-dns-filtering-workaround
This commit is contained in:
commit
459c05a033
15 changed files with 458 additions and 64 deletions
|
@ -21,6 +21,7 @@ addons:
|
|||
- expect-dev
|
||||
- debootstrap
|
||||
- shellcheck
|
||||
- tree
|
||||
|
||||
cache:
|
||||
directories:
|
||||
|
@ -51,9 +52,12 @@ install:
|
|||
- chmod 0644 ~/.ssh/config
|
||||
- sudo mkdir -vm 0700 $LXC_ROOTFS/root/.ssh/
|
||||
- sudo cp -v ~/.ssh/id_rsa.pub $LXC_ROOTFS/root/.ssh/authorized_keys
|
||||
- sudo apt-get install build-essential libssl-dev libffi-dev python-dev && sudo pip install -r requirements.txt
|
||||
- sudo apt-get install build-essential libssl-dev libffi-dev python-dev
|
||||
- pip install -r requirements.txt
|
||||
- pip install ansible-lint
|
||||
- gem install awesome_bot
|
||||
- ansible-playbook --version
|
||||
- tree . -L 2
|
||||
|
||||
script:
|
||||
# - awesome_bot --allow-dupe --skip-save-results *.md docs/*.md --white-list paypal.com,do.co,microsoft.com,https://github.com/trailofbits/algo/archive/master.zip,https://github.com/trailofbits/algo/issues/new
|
||||
|
|
|
@ -56,7 +56,10 @@ The easiest way to get an Algo server running is to let it set up a _new_ virtua
|
|||
|
||||
4. **Install Algo's remaining dependencies.** Use the same Terminal window as the previous step and run:
|
||||
```bash
|
||||
$ python -m virtualenv --python=`which python2` env && source env/bin/activate && python -m pip install -U pip && python -m pip install -r requirements.txt
|
||||
$ python -m virtualenv --python=`which python2` env &&
|
||||
source env/bin/activate &&
|
||||
python -m pip install -U pip &&
|
||||
python -m pip install -r requirements.txt
|
||||
```
|
||||
On macOS, you may be prompted to install `cc`. You should press accept if so.
|
||||
|
||||
|
@ -98,9 +101,9 @@ No version of Android supports IKEv2. Install the [strongSwan VPN Client for And
|
|||
|
||||
### Windows 10
|
||||
|
||||
Copy your PowerShell script `windows_{username}.ps1` and p12 certificate `{username}.p12` to the Windows client and run the following command as Administrator to configure the VPN connection.
|
||||
Copy your PowerShell script `windows_{username}.ps1` to the Windows client and run the following command as Administrator to configure the VPN connection.
|
||||
```
|
||||
powershell -ExecutionPolicy ByPass -File windows_{username}.ps1 Add
|
||||
powershell -ExecutionPolicy ByPass -File windows_{username}.ps1 -Add
|
||||
```
|
||||
|
||||
For a manual installation, see the [Windows setup instructions](/docs/client-windows.md).
|
||||
|
|
4
algo
4
algo
|
@ -281,7 +281,7 @@ Enter the number of your desired region:
|
|||
esac
|
||||
|
||||
ROLES="ec2 vpn cloud"
|
||||
EXTRA_VARS="aws_access_key=$aws_access_key aws_secret_key=$aws_secret_key aws_server_name=$aws_server_name ssh_public_key=$ssh_public_key region=$region"
|
||||
EXTRA_VARS="aws_access_key=$aws_access_key aws_secret_key=$aws_secret_key aws_server_name=$aws_server_name region=$region"
|
||||
}
|
||||
|
||||
lightsail () {
|
||||
|
@ -542,7 +542,7 @@ algo_provisioning () {
|
|||
5. Google Compute Engine
|
||||
6. Scaleway
|
||||
7. OpenStack (DreamCompute optimised)
|
||||
8. Install to existing Ubuntu 16.04 server
|
||||
8. Install to existing Ubuntu 16.04 server (Advanced)
|
||||
|
||||
Enter the number of your desired provider
|
||||
: "
|
||||
|
|
|
@ -1,27 +1,69 @@
|
|||
# Windows client manual setup
|
||||
|
||||
Windows clients have a more complicated setup than most others. Follow the steps below to set one up:
|
||||
## Automatic installtion
|
||||
|
||||
1. Copy the CA certificate (`cacert.pem`), user certificate (`$user.p12`), and the user PowerShell script (`windows_$user.ps1`) to the client computer.
|
||||
2. Import the CA certificate to the local machine Trusted Root certificate store.
|
||||
3. Open PowerShell as Administrator. Navigate to your copied files.
|
||||
4. If you haven't already, you will need to change the Execution Policy to allow unsigned scripts to run.
|
||||
To install automatically, use the generated user Powershell script.
|
||||
|
||||
1. Copy the user PowerShell script (`windows_USER.ps1`) to the client computer.
|
||||
2. Open Powershell as Administrator.
|
||||
3. Run the following command:
|
||||
```powershell
|
||||
powershell -ExecutionPolicy ByPass -File C:\path\to\windows_USER.ps1 -Add
|
||||
```
|
||||
4. The command has help information available. To view its full help, run this from Powershell:
|
||||
```powershell
|
||||
Get-Help -Name .\windows_USER.ps1 -Full | more
|
||||
```
|
||||
|
||||
## Manual installation
|
||||
|
||||
1. Copy the CA certificate (`cacert.pem`) and user certificate (`USER.p12`) to the client computer
|
||||
2. Open PowerShell as Administrator. Navigate to your copied files.
|
||||
3. If you haven't already, you will need to change the Execution Policy to allow unsigned scripts to run.
|
||||
|
||||
```powershell
|
||||
Set-ExecutionPolicy Unrestricted -Scope CurrentUser
|
||||
```
|
||||
|
||||
5. In the same PowerShell window, run the included PowerShell script to import the user certificate, set up a VPN connection, and activate stronger ciphers on it.
|
||||
6. After you execute the user script, set the Execution Policy back before you close the PowerShell window.
|
||||
4. In the same window, run the necessary commands to install the certificates and create the VPN configuration. Note the lines at the top defining the VPN address, USER.p12 file location, and CA certificate location - change those lines to the IP address of your Algo server and the location you saved those two files. Also note that it will prompt for the "User p12 password", which is printed at the end of a successful Algo deployment.
|
||||
|
||||
```powershell
|
||||
$VpnServerAddress = "1.2.3.4"
|
||||
$UserP12Path = "$Home\Downloads\USER.p12"
|
||||
$CaCertPath = "$Home\Downloads\cacert.pem"
|
||||
$VpnName = "Algo VPN $VpnServerAddress IKEv2"
|
||||
$p12Pass = Read-Host -AsSecureString -Prompt "User p12 password"
|
||||
|
||||
Import-PfxCertificate -FilePath $UserP12Path -CertStoreLocation Cert:\LocalMachine\My -Password $p12Pass
|
||||
Import-Certificate -FilePath $CaCertPath -CertStoreLocation Cert:\LocalMachine\Root
|
||||
|
||||
$addVpnParams = @{
|
||||
Name = $VpnName
|
||||
ServerAddress = $VpnServerAddress
|
||||
TunnelType = "IKEv2"
|
||||
AuthenticationMethod = "MachineCertificate"
|
||||
EncryptionLevel = "Required"
|
||||
}
|
||||
Add-VpnConnection @addVpnParams
|
||||
|
||||
$setVpnParams = @{
|
||||
ConnectionName = $VpnName
|
||||
AuthenticationTransformConstants = "GCMAES128"
|
||||
CipherTransformConstants = "GCMAES128"
|
||||
EncryptionMethod = "AES128"
|
||||
IntegrityCheckMethod = "SHA384"
|
||||
DHGroup = "ECP256"
|
||||
PfsGroup = "ECP256"
|
||||
Force = $true
|
||||
}
|
||||
Set-VpnConnectionIPsecConfiguration @setVpnParams
|
||||
|
||||
```
|
||||
|
||||
5. After you execute the user script, set the Execution Policy back before you close the PowerShell window.
|
||||
|
||||
```powershell
|
||||
Set-ExecutionPolicy Restricted -Scope CurrentUser
|
||||
```
|
||||
|
||||
Your VPN is now installed and ready to use.
|
||||
|
||||
If you want to perform these steps by hand, you will need to import the user certificate to the Personal certificate store, add an IKEv2 connection in the network settings, then activate stronger ciphers on it via the following PowerShell script:
|
||||
|
||||
```powershell
|
||||
Set-VpnConnectionIPsecConfiguration -ConnectionName "Algo" -AuthenticationTransformConstants GCMAES128 -CipherTransformConstants GCMAES128 -EncryptionMethod AES128 -IntegrityCheckMethod SHA384 -DHGroup ECP256 -PfsGroup ECP256
|
||||
```
|
||||
|
|
|
@ -87,7 +87,6 @@ Required variables:
|
|||
- aws_access_key
|
||||
- aws_secret_key
|
||||
- aws_server_name
|
||||
- ssh_public_key
|
||||
- region
|
||||
|
||||
Possible options for `region`:
|
||||
|
|
21
docs/faq.md
21
docs/faq.md
|
@ -9,6 +9,7 @@
|
|||
* [I deployed an Algo server. Can you update it with new features?](#i-deployed-an-algo-server-can-you-update-it-with-new-features)
|
||||
* [Where did the name "Algo" come from?](#where-did-the-name-algo-come-from)
|
||||
* [Can DNS filtering be disabled?](#can-dns-filtering-be-disabled)
|
||||
* [Wasn't IPSEC backdoored by the US government?](#wasnt-ipsec-backdoored-by-the-us-government)
|
||||
|
||||
## Has Algo been audited?
|
||||
|
||||
|
@ -49,3 +50,23 @@ Algo is short for "Al Gore", the **V**ice **P**resident of **N**etworks everywhe
|
|||
## Can DNS filtering be disabled?
|
||||
|
||||
There is no official way to disable DNS filtering, but there is a workaround: SSH to your Algo server (using the 'shell access' command printed upon a successful deployment), edit `/etc/ipsec.conf`, and change `rightdns=172.16.0.1` to `rightdns=8.8.8.8`. Then run `ipsec restart`. If all else fails, we recommend deploying a new Algo server without the adblocking feature enabled.
|
||||
|
||||
## Wasn't IPSEC backdoored by the US government?
|
||||
|
||||
No.
|
||||
|
||||
[Per security researcher Thomas Ptacek](https://news.ycombinator.com/item?id=2014197):
|
||||
|
||||
> In 2001, Angelos Keromytis --- then a grad student at Penn, now a Columbia professor --- added support for hardware-accelerated IPSEC NICs. When you have an IPSEC NIC, the channel between the NIC and the IPSEC stack keeps state to tell the stack not to bother doing the things the NIC already did, among them validating the IPSEC ESP authenticator. Angelos' code had a bug; it appears to have done the software check only when the hardware had already done it, and skipped it otherwise.
|
||||
>
|
||||
> The bug happened during a change that simultaneously refactored and added a feature to OpenBSD's ESP code; a comparison that should have been == was instead !=; the "if" statement with the bug was originally and correctly !=, but should have been flipped based on how the code was refactored.
|
||||
>
|
||||
> HD Moore may as we speak be going through the pain of reconstituting a nearly decade-old version of OpenBSD to verify the bug, but stipulate that it was there, and here's what you get: IPSEC ESP packet authentication was disabled if you didn't have hardware IPSEC. There is probably an elaborate man-in-the-middle scenario in which this could get you traffic inspection, but it's nowhere nearly as straightforward as leaking key bits.
|
||||
>
|
||||
> To entertain the conspiracy theory, you're still suggesting that the FBI not only introduced this bug, but also developed the technology required to MITM ESP sessions, bouncing them through some secret FBI-developed middlebox.
|
||||
>
|
||||
> One year later, Jason Wright from NETSEC (the company at the heart of the [I think silly] allegations about OpenBSD IPSEC backdoors) fixed the bug.
|
||||
>
|
||||
> It's interesting that the bug was fixed without an advisory (oh to be a fly on the wall on ICB that day; Theo had a, um, a, "way" with his dev team). On the other hand, we don't know what releases of OpenBSD actually had the bug right now.
|
||||
>
|
||||
> It seems vanishingly unlikely that there could have been anything deliberate about this series of changes. You are unlikely to find anyone who will impugn Angelos. Meanwhile, the diffs tell exactly the opposite of the story that Greg Perry told.
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
blockinfile:
|
||||
dest: configs/inventory.dynamic
|
||||
marker: "# {mark} ALGO MANAGED BLOCK"
|
||||
create: yes
|
||||
create: true
|
||||
block: |
|
||||
[algo:children]
|
||||
{% for group in cloud_providers.keys() %}
|
||||
|
|
67
playbooks/win_script_rebuild.yml
Normal file
67
playbooks/win_script_rebuild.yml
Normal file
|
@ -0,0 +1,67 @@
|
|||
---
|
||||
|
||||
# This playbook is designed to help when modifying the Windows script template
|
||||
# in roles/vpn/templates/client_windows.ps1.j2
|
||||
# It rebuilds the client_USER.ps1 scripts for each user defined in config.cfg,
|
||||
# without redeploying users or opening an SSH connection to the Algo server at
|
||||
# all.
|
||||
#
|
||||
# This playbook is _not_ part of a normal Algo deployment.
|
||||
# It is only intended to speed up development of the client_USER.ps1 Windows
|
||||
# Algo install scripts.
|
||||
#
|
||||
# REQUIREMENTS
|
||||
# - Algo must have been deployed once
|
||||
# - Windows users must have been enabled at deployment time
|
||||
# - All users defined in config.cfg must not have changed
|
||||
# - Only one Algo deployment exists in the configs/ directory
|
||||
# - There must be exactly one subfolder in the configs/ directory:
|
||||
# the folder named after the IP of the algo server
|
||||
|
||||
- hosts: localhost
|
||||
gather_facts: False
|
||||
tags: always
|
||||
vars_files:
|
||||
- ../config.cfg
|
||||
|
||||
tasks:
|
||||
|
||||
- name: Get config subdir
|
||||
shell: find ../configs/* -maxdepth 0 -type d | sed 's/.*\///'
|
||||
register: config_subdir_result
|
||||
- fail:
|
||||
msg:
|
||||
- "Found wrong number of config subdirs... stdout:"
|
||||
- "{{ config_subdir_result.split('\n') }}"
|
||||
when: config_subdir_result.stdout.split('\n') | length != 1
|
||||
- set_fact:
|
||||
IP_subject_alt_name: "{{ config_subdir_result.stdout }}"
|
||||
- debug:
|
||||
var: IP_subject_alt_name
|
||||
|
||||
- name: Register p12 PayloadContent
|
||||
shell: cat private/{{ item }}.p12 | base64
|
||||
register: PayloadContent
|
||||
args:
|
||||
chdir: "../configs/{{ IP_subject_alt_name }}/pki/"
|
||||
with_items: "{{ users }}"
|
||||
|
||||
- name: Set facts for mobileconfigs
|
||||
set_fact:
|
||||
proxy_enabled: false
|
||||
PayloadContentCA: "{{ lookup('file' , '../configs/{{ IP_subject_alt_name }}/pki/cacert.pem')|b64encode }}"
|
||||
|
||||
- name: Build the windows client powershell script
|
||||
template:
|
||||
src: ../roles/vpn/templates/client_windows.ps1.j2
|
||||
dest: ../configs/{{ IP_subject_alt_name }}/windows_{{ item.0 }}.ps1
|
||||
mode: 0600
|
||||
with_together:
|
||||
- "{{ users }}"
|
||||
- "{{ PayloadContent.results }}"
|
||||
|
||||
- name: List windows client powershell scripts
|
||||
debug:
|
||||
msg: "configs/{{ IP_subject_alt_name }}/windows_{{ item }}.ps1"
|
||||
with_items:
|
||||
- "{{ users }}"
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
- name: Set facts for mobileconfigs
|
||||
set_fact:
|
||||
proxy_enabled: false
|
||||
PayloadContentCA: "{{ lookup('file' , 'configs/{{ IP_subject_alt_name }}/pki/cacert.pem')|b64encode }}"
|
||||
|
||||
- name: Build the mobileconfigs
|
||||
|
@ -71,10 +70,12 @@
|
|||
- name: Build the windows client powershell script
|
||||
template:
|
||||
src: client_windows.ps1.j2
|
||||
dest: configs/{{ IP_subject_alt_name }}/windows_{{ item }}.ps1
|
||||
dest: configs/{{ IP_subject_alt_name }}/windows_{{ item.0 }}.ps1
|
||||
mode: 0600
|
||||
when: Win10_Enabled is defined and Win10_Enabled == "Y" or supports_windows.stat.exists == true
|
||||
with_items: "{{ users }}"
|
||||
with_together:
|
||||
- "{{ users }}"
|
||||
- "{{ PayloadContent.results }}"
|
||||
|
||||
- name: Restrict permissions for the local private directories
|
||||
file:
|
||||
|
|
|
@ -1,19 +1,198 @@
|
|||
#Requires -RunAsAdministrator
|
||||
|
||||
function AddAlgoVPN {
|
||||
certutil -f -importpfx .\{{ item }}.p12
|
||||
certutil -addstore root .\cacert.pem
|
||||
Add-VpnConnection -name "Algo VPN {{ IP_subject_alt_name }} IKEv2" -ServerAddress "{{ IP_subject_alt_name }}" -TunnelType IKEv2 -AuthenticationMethod MachineCertificate -EncryptionLevel Required
|
||||
Set-VpnConnectionIPsecConfiguration -ConnectionName "Algo VPN {{ IP_subject_alt_name }} IKEv2" -AuthenticationTransformConstants GCMAES128 -CipherTransformConstants GCMAES128 -EncryptionMethod AES128 -IntegrityCheckMethod SHA384 -DHGroup ECP256 -PfsGroup ECP256 -Force
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Add or remove the Algo VPN
|
||||
|
||||
.DESCRIPTION
|
||||
Add or remove the Algo VPN
|
||||
See the examples for more information
|
||||
|
||||
.PARAMETER Add
|
||||
Add the VPN to the local system
|
||||
|
||||
.PARAMETER Remove
|
||||
Remove the VPN from the local system
|
||||
|
||||
.PARAMETER GetInstalledCerts
|
||||
Retrieve Algo certs, if any, from the system certificate store
|
||||
|
||||
.PARAMETER SaveCerts
|
||||
Save the Algo certs embedded in this file
|
||||
|
||||
.PARAMETER OutputDirectory
|
||||
When saving the Algo certs, save to this directory
|
||||
|
||||
.PARAMETER Pkcs12DecryptionPassword
|
||||
The decryption password for the user's PKCS12 certificate, sometimes called the "p12 password".
|
||||
Note that this must be passed in as a SecureString, not a regular string.
|
||||
You can create a secure string with the `Read-Host -AsSecureString` cmdlet.
|
||||
See the examples for more information.
|
||||
|
||||
.EXAMPLE
|
||||
client_USER.ps1 -Add
|
||||
|
||||
Adds the Algo VPN
|
||||
|
||||
.EXAMPLE
|
||||
$p12pass = Read-Host -AsSecureString; client_USER.ps1 -Add -Pkcs12DecryptionPassword $p12pass
|
||||
|
||||
Create a variable containing the PKCS12 decryption password, then use it when adding the VPN.
|
||||
This can be especially useful when troubleshooting, because you can use the same variable with
|
||||
multiple calls to client_USER.ps1, rather than having to type the PKCS12 password each time.
|
||||
|
||||
.EXAMPLE
|
||||
client_USER.ps1 -Remove
|
||||
|
||||
Removes the Algo VPN if installed.
|
||||
|
||||
.EXAMPLE
|
||||
client_USER.ps1 -GetIntalledCerts
|
||||
|
||||
Show the Algo VPN's installed certificates, if any.
|
||||
|
||||
.EXAMPLE
|
||||
client_USER.ps1 -SaveCerts -OutputDirectory $Home\Downloads
|
||||
|
||||
Save the embedded CA cert and encrypted user PKCS12 file.
|
||||
#>
|
||||
[CmdletBinding(DefaultParameterSetName="Add")] Param(
|
||||
[Parameter(ParameterSetName="Add")]
|
||||
[Switch] $Add,
|
||||
|
||||
[Parameter(ParameterSetName="Add")]
|
||||
[SecureString] $Pkcs12DecryptionPassword,
|
||||
|
||||
[Parameter(Mandatory, ParameterSetName="Remove")]
|
||||
[Switch] $Remove,
|
||||
|
||||
[Parameter(Mandatory, ParameterSetName="GetInstalledCerts")]
|
||||
[Switch] $GetInstalledCerts,
|
||||
|
||||
[Parameter(Mandatory, ParameterSetName="SaveCerts")]
|
||||
[Switch] $SaveCerts,
|
||||
|
||||
[Parameter(ParameterSetName="SaveCerts")]
|
||||
[string] $OutputDirectory = "$PWD"
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
$VpnServerAddress = "{{ IP_subject_alt_name }}"
|
||||
$VpnName = "Algo VPN {{ IP_subject_alt_name }} IKEv2"
|
||||
$VpnUser = "{{ item.0 }}"
|
||||
$CaCertificateBase64 = "{{ PayloadContentCA }}"
|
||||
$UserPkcs12Base64 = "{{ item.1.stdout }}"
|
||||
|
||||
if ($PsCmdlet.ParameterSetName -eq "Add" -and -not $Pkcs12DecryptionPassword) {
|
||||
$Pkcs12DecryptionPassword = Read-Host -AsSecureString -Prompt "Pkcs12DecryptionPassword"
|
||||
}
|
||||
|
||||
function RemoveAlgoVPN {
|
||||
Get-ChildItem cert:LocalMachine/Root | Where-Object { $_.Subject -match '^CN={{ IP_subject_alt_name }}$' -and $_.Issuer -match '^CN={{ IP_subject_alt_name }}$' } | Remove-Item
|
||||
Get-ChildItem cert:LocalMachine/My | Where-Object { $_.Subject -match '^CN={{ item }}$' -and $_.Issuer -match '^CN={{ IP_subject_alt_name }}$' } | Remove-Item
|
||||
Remove-VpnConnection -name "Algo VPN {{ IP_subject_alt_name }} IKEv2" -Force
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Create a temporary directory
|
||||
#>
|
||||
function New-TemporaryDirectory {
|
||||
[CmdletBinding()] Param()
|
||||
do {
|
||||
$guid = New-Guid | Select-Object -ExpandProperty Guid
|
||||
$newTempDirPath = Join-Path -Path $env:TEMP -ChildPath $guid
|
||||
} while (Test-Path -Path $newTempDirPath)
|
||||
New-Item -ItemType Directory -Path $newTempDirPath
|
||||
}
|
||||
|
||||
switch ($args[0]) {
|
||||
"Add" { AddAlgoVPN }
|
||||
"Remove" { RemoveAlgoVPN }
|
||||
default { Write-Host Usage: $MyInvocation.MyCommand.Name "(Add|Remove)" }
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Retrieve any installed Algo VPN certificates
|
||||
#>
|
||||
function Get-InstalledAlgoVpnCertificates {
|
||||
[CmdletBinding()] Param()
|
||||
Get-ChildItem -LiteralPath Cert:\LocalMachine\Root |
|
||||
Where-Object {
|
||||
$_.Subject -match "^CN=${VpnServerAddress}$" -and $_.Issuer -match "^CN=${VpnServerAddress}$"
|
||||
}
|
||||
Get-ChildItem -LiteralPath Cert:\LocalMachine\My |
|
||||
Where-Object {
|
||||
$_.Subject -match "^CN=${VpnUser}$" -and $_.Issuer -match "^CN=${VpnServerAddress}$"
|
||||
}
|
||||
}
|
||||
|
||||
function Save-AlgoVpnCertificates {
|
||||
[CmdletBinding()] Param(
|
||||
[String] $OutputDirectory = $PWD
|
||||
)
|
||||
$caCertPath = Join-Path -Path $OutputDirectory -ChildPath "cacert.pem"
|
||||
$userP12Path = Join-Path -Path $OutputDirectory -ChildPath "$VpnUser.p12"
|
||||
# NOTE: We cannot use ConvertFrom-Base64 here because it is not designed for binary data
|
||||
[IO.File]::WriteAllBytes(
|
||||
$caCertPath,
|
||||
[Convert]::FromBase64String($CaCertificateBase64))
|
||||
[IO.File]::WriteAllBytes(
|
||||
$userP12Path,
|
||||
[Convert]::FromBase64String($UserPkcs12Base64))
|
||||
return New-Object -TypeName PSObject -Property @{
|
||||
CaPem = $caCertPath
|
||||
UserPkcs12 = $userP12Path
|
||||
}
|
||||
}
|
||||
|
||||
function Add-AlgoVPN {
|
||||
[Cmdletbinding()] Param()
|
||||
|
||||
$workDir = New-TemporaryDirectory
|
||||
|
||||
try {
|
||||
$certs = Save-AlgoVpnCertificates -OutputDirectory $workDir
|
||||
$importPfxCertParams = @{
|
||||
Password = $Pkcs12DecryptionPassword
|
||||
FilePath = $certs.UserPkcs12
|
||||
CertStoreLocation = "Cert:\LocalMachine\My"
|
||||
}
|
||||
Import-PfxCertificate @importPfxCertParams
|
||||
$importCertParams = @{
|
||||
FilePath = $certs.CaPem
|
||||
CertStoreLocation = "Cert:\LocalMachine\Root"
|
||||
}
|
||||
Import-Certificate @importCertParams
|
||||
} finally {
|
||||
Remove-Item -Recurse -Force -LiteralPath $workDir
|
||||
}
|
||||
|
||||
$addVpnParams = @{
|
||||
Name = $VpnName
|
||||
ServerAddress = $VpnServerAddress
|
||||
TunnelType = "IKEv2"
|
||||
AuthenticationMethod = "MachineCertificate"
|
||||
EncryptionLevel = "Required"
|
||||
}
|
||||
Add-VpnConnection @addVpnParams
|
||||
|
||||
$setVpnParams = @{
|
||||
ConnectionName = $VpnName
|
||||
AuthenticationTransformConstants = "GCMAES128"
|
||||
CipherTransformConstants = "GCMAES128"
|
||||
EncryptionMethod = "AES128"
|
||||
IntegrityCheckMethod = "SHA384"
|
||||
DHGroup = "ECP256"
|
||||
PfsGroup = "ECP256"
|
||||
Force = $true
|
||||
}
|
||||
Set-VpnConnectionIPsecConfiguration @setVpnParams
|
||||
}
|
||||
|
||||
function Remove-AlgoVPN {
|
||||
[CmdletBinding()] Param()
|
||||
Get-InstalledAlgoVpnCertificates | Remove-Item -Force
|
||||
Remove-VpnConnection -Name $VpnName -Force
|
||||
}
|
||||
|
||||
switch ($PsCmdlet.ParameterSetName) {
|
||||
"Add" { Add-AlgoVPN }
|
||||
"Remove" { Remove-AlgoVPN }
|
||||
"GetInstalledCerts" { Get-InstalledAlgoVpnCertificates }
|
||||
"SaveCerts" {
|
||||
$certs = Save-AlgoVpnCertificates -OutputDirectory $OutputDirectory
|
||||
Get-Item -LiteralPath $certs.UserPkcs12, $certs.CaPem
|
||||
}
|
||||
default { throw "Unknown parameter set: '$($PsCmdlet.ParameterSetName)'" }
|
||||
}
|
||||
|
|
|
@ -124,24 +124,12 @@
|
|||
<key>Proxies</key>
|
||||
<dict>
|
||||
<key>HTTPEnable</key>
|
||||
{% if proxy_enabled is defined and proxy_enabled == true %}
|
||||
<integer>1</integer>
|
||||
<key>HTTPPort</key>
|
||||
<integer>8118</integer>
|
||||
<key>HTTPProxy</key>
|
||||
<string>{{ local_service_ip }}</string>
|
||||
{% else %}
|
||||
<integer>0</integer>
|
||||
{% endif %}
|
||||
<key>HTTPSEnable</key>
|
||||
<integer>0</integer>
|
||||
</dict>
|
||||
<key>UserDefinedName</key>
|
||||
{% if proxy_enabled is defined and proxy_enabled == true %}
|
||||
<string>Algo VPN {{ IP_subject_alt_name }} IKEv2 with proxy</string>
|
||||
{% else %}
|
||||
<string>Algo VPN {{ IP_subject_alt_name }} IKEv2</string>
|
||||
{% endif %}
|
||||
<key>VPNType</key>
|
||||
<string>IKEv2</string>
|
||||
</dict>
|
||||
|
@ -187,17 +175,9 @@
|
|||
</dict>
|
||||
</array>
|
||||
<key>PayloadDisplayName</key>
|
||||
{% if proxy_enabled is defined and proxy_enabled == true %}
|
||||
<string>{{ IP_subject_alt_name }} IKEv2 with proxy</string>
|
||||
{% else %}
|
||||
<string>{{ IP_subject_alt_name }} IKEv2</string>
|
||||
{% endif %}
|
||||
<key>PayloadIdentifier</key>
|
||||
{% if proxy_enabled is defined and proxy_enabled == true %}
|
||||
<string>donut.local.{{ 600000 | random | to_uuid | upper }}</string>
|
||||
{% else %}
|
||||
<string>donut.local.{{ 500000 | random | to_uuid | upper }}</string>
|
||||
{% endif %}
|
||||
<key>PayloadRemovalDisallowed</key>
|
||||
<false/>
|
||||
<key>PayloadType</key>
|
||||
|
|
|
@ -1,43 +1,95 @@
|
|||
#### The mangle table
|
||||
# This table allows us to modify packet headers
|
||||
# Packets enter this table first
|
||||
#
|
||||
*mangle
|
||||
|
||||
:PREROUTING ACCEPT [0:0]
|
||||
:INPUT ACCEPT [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
:POSTROUTING ACCEPT [0:0]
|
||||
|
||||
{% if max_mss is defined %}
|
||||
# MSS is the TCP Max Segment Size
|
||||
# Setting the 'max_mss' Ansible variable can solve some issues related to packet fragmentation
|
||||
# This appears to be necessary on (at least) Google Cloud,
|
||||
# however, some routers also require a change to this parameter
|
||||
# See also:
|
||||
# - https://github.com/trailofbits/algo/issues/216
|
||||
# - https://github.com/trailofbits/algo/issues?utf8=%E2%9C%93&q=is%3Aissue%20mtu
|
||||
# - https://serverfault.com/questions/601143/ssh-not-working-over-ipsec-tunnel-strongswan
|
||||
-A FORWARD -s {{ vpn_network }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ max_mss }}
|
||||
{% endif %}
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
#### The nat table
|
||||
# This table enables Network Address Translation
|
||||
# (This is technically a type of packet mangling)
|
||||
#
|
||||
*nat
|
||||
|
||||
:PREROUTING ACCEPT [0:0]
|
||||
:POSTROUTING ACCEPT [0:0]
|
||||
|
||||
# Allow traffic from the VPN network to the outside world, and replies
|
||||
-A POSTROUTING -s {{ vpn_network }} -m policy --pol none --dir out -j MASQUERADE
|
||||
|
||||
COMMIT
|
||||
|
||||
|
||||
#### The filter table
|
||||
# The default ipfilter table
|
||||
#
|
||||
*filter
|
||||
|
||||
# By default, drop packets that are destined for this server
|
||||
:INPUT DROP [0:0]
|
||||
# By default, drop packets that request to be forwarded by this server
|
||||
:FORWARD DROP [0:0]
|
||||
# By default, accept any packets originating from this server
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
|
||||
# Accept packets destined for localhost
|
||||
-A INPUT -i lo -j ACCEPT
|
||||
# Accept any packet from an open TCP connection
|
||||
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
# Accept packets using the encapsulation protocol
|
||||
-A INPUT -p esp -j ACCEPT
|
||||
-A INPUT -p ah -j ACCEPT
|
||||
# rate limit ICMP traffic per source
|
||||
-A INPUT -p icmp --icmp-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT
|
||||
# Accept IPSEC traffic to ports 500 (IPSEC) and 4500 (MOBIKE aka IKE + NAT traversal)
|
||||
-A INPUT -p udp -m multiport --dports 500,4500 -j ACCEPT
|
||||
# Allow new traffic to port 22 (SSH)
|
||||
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
|
||||
# Allow any traffic from the VPN
|
||||
-A INPUT -p ipencap -m policy --dir in --pol ipsec --proto esp -j ACCEPT
|
||||
|
||||
# TODO:
|
||||
# The IP of the resolver should be bound to a DUMMY interface.
|
||||
# DUMMY interfaces are the proper way to install IPs without assigning them any
|
||||
# particular virtual (tun,tap,...) or physical (ethernet) interface.
|
||||
|
||||
# Accept DNS traffic to the local DNS resolver
|
||||
-A INPUT -d {{ local_service_ip }} -p udp --dport 53 -j ACCEPT
|
||||
-A INPUT -d {{ local_service_ip }} -p tcp -m multiport --dport 8080,8118 -j ACCEPT
|
||||
|
||||
{% if BetweenClients_DROP is defined and BetweenClients_DROP == "Y" %}
|
||||
# Drop traffic between VPN clients
|
||||
-A FORWARD -s {{ vpn_network }} -d {{ vpn_network }} -j DROP
|
||||
{% endif %}
|
||||
|
||||
# Forward any packet that's part of an established connection
|
||||
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
# Drop SMB/CIFS traffic that requests to be forwarded
|
||||
-A FORWARD -p tcp --dport 445 -j DROP
|
||||
# Drop NETBIOS trafic that requests to be forwarded
|
||||
-A FORWARD -p udp -m multiport --ports 137,138 -j DROP
|
||||
-A FORWARD -p tcp -m multiport --ports 137,139 -j DROP
|
||||
|
||||
# Forward any IPSEC traffic from the VPN network
|
||||
-A FORWARD -m conntrack --ctstate NEW -s {{ vpn_network }} -m policy --pol ipsec --dir in -j ACCEPT
|
||||
|
||||
COMMIT
|
||||
|
|
|
@ -1,43 +1,89 @@
|
|||
#### The mangle table
|
||||
# This table allows us to modify packet headers
|
||||
# Packets enter this table first
|
||||
#
|
||||
*mangle
|
||||
|
||||
:PREROUTING ACCEPT [0:0]
|
||||
:INPUT ACCEPT [0:0]
|
||||
:FORWARD ACCEPT [0:0]
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
:POSTROUTING ACCEPT [0:0]
|
||||
|
||||
{% if max_mss is defined %}
|
||||
# MSS is the TCP Max Segment Size
|
||||
# See rules.v4 for a more complete explanation
|
||||
-A FORWARD -s {{ vpn_network_ipv6 }} -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss {{ max_mss }}
|
||||
{% endif %}
|
||||
|
||||
COMMIT
|
||||
|
||||
#### The nat table
|
||||
# This table enables Network Address Translation
|
||||
# (This is technically a type of packet mangling)
|
||||
#
|
||||
*nat
|
||||
|
||||
:PREROUTING ACCEPT [0:0]
|
||||
:POSTROUTING ACCEPT [0:0]
|
||||
|
||||
# Allow traffic from the VPN network to the outside world, and replies
|
||||
-A POSTROUTING -s {{ vpn_network_ipv6 }} -m policy --pol none --dir out -j MASQUERADE
|
||||
|
||||
COMMIT
|
||||
|
||||
#### The filter table
|
||||
# The default ipfilter table
|
||||
#
|
||||
*filter
|
||||
|
||||
# By default, drop packets that are destined for this server
|
||||
:INPUT DROP [0:0]
|
||||
# By default, drop packets that request to be forwarded by this server
|
||||
:FORWARD DROP [0:0]
|
||||
# By default, accept any packets originating from this server
|
||||
:OUTPUT ACCEPT [0:0]
|
||||
|
||||
# Create the ICMPV6-CHECK chain and its log chain
|
||||
# These chains are used later to prevent a type of bug that would
|
||||
# allow malicious traffic to reach over the server into the private network
|
||||
# An instance of such a bug on Cisco software is described here:
|
||||
# https://www.insinuator.net/2016/05/cve-2016-1409-ipv6-ndp-dos-vulnerability-in-cisco-software/
|
||||
# other software implementations might be at least as broken as the one in CISCO gear.
|
||||
:ICMPV6-CHECK - [0:0]
|
||||
:ICMPV6-CHECK-LOG - [0:0]
|
||||
|
||||
# Accept packets destined for localhost
|
||||
-A INPUT -i lo -j ACCEPT
|
||||
# Accept any packet from an open TCP connection
|
||||
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
# Accept packets using the encapsulation protocol
|
||||
-A INPUT -p esp -j ACCEPT
|
||||
-A INPUT -m ah -j ACCEPT
|
||||
# rate limit ICMP traffic per source
|
||||
-A INPUT -p icmpv6 --icmpv6-type echo-request -m hashlimit --hashlimit-upto 5/s --hashlimit-mode srcip --hashlimit-srcmask 32 --hashlimit-name icmp-echo-drop -j ACCEPT
|
||||
# Accept IPSEC traffic to ports 500 (IPSEC) and 4500 (MOBIKE aka IKE + NAT traversal)
|
||||
-A INPUT -p udp -m multiport --dports 500,4500 -j ACCEPT
|
||||
# Allow new traffic to port 22 (SSH)
|
||||
-A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT
|
||||
|
||||
# Accept properly formatted Neighbor Discovery Protocol packets
|
||||
-A INPUT -p icmpv6 --icmpv6-type router-advertisement -m hl --hl-eq 255 -j ACCEPT
|
||||
-A INPUT -p icmpv6 --icmpv6-type neighbor-solicitation -m hl --hl-eq 255 -j ACCEPT
|
||||
-A INPUT -p icmpv6 --icmpv6-type neighbor-advertisement -m hl --hl-eq 255 -j ACCEPT
|
||||
-A INPUT -p icmpv6 --icmpv6-type redirect -m hl --hl-eq 255 -j ACCEPT
|
||||
|
||||
# DHCP in AWS
|
||||
-A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 546 -d fe80::/64 -j ACCEPT
|
||||
|
||||
# TODO:
|
||||
# The IP of the resolver should be bound to a DUMMY interface.
|
||||
# DUMMY interfaces are the proper way to install IPs without assigning them any
|
||||
# particular virtual (tun,tap,...) or physical (ethernet) interface.
|
||||
|
||||
# Accept DNS traffic to the local DNS resolver
|
||||
-A INPUT -d fcaa::1 -p udp --dport 53 -j ACCEPT
|
||||
|
||||
{% if BetweenClients_DROP is defined and BetweenClients_DROP == "Y" %}
|
||||
-A FORWARD -s {{ vpn_network_ipv6 }} -d {{ vpn_network_ipv6 }} -j DROP
|
||||
{% endif %}
|
||||
|
@ -47,13 +93,13 @@ COMMIT
|
|||
-A FORWARD -p tcp -m multiport --ports 137,139 -j DROP
|
||||
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
|
||||
-A FORWARD -m conntrack --ctstate NEW -s {{ vpn_network_ipv6 }} -m policy --pol ipsec --dir in -j ACCEPT
|
||||
# this is so potential malicious traffic can not reach anywhere over the server
|
||||
# https://www.insinuator.net/2016/05/cve-2016-1409-ipv6-ndp-dos-vulnerability-in-cisco-software/
|
||||
# other software implementations might be at least as broken as the one in CISCO gear.
|
||||
|
||||
# Use the ICMPV6-CHECK chain, described above
|
||||
-A ICMPV6-CHECK -p icmpv6 -m hl ! --hl-eq 255 --icmpv6-type router-solicitation -j ICMPV6-CHECK-LOG
|
||||
-A ICMPV6-CHECK -p icmpv6 -m hl ! --hl-eq 255 --icmpv6-type router-advertisement -j ICMPV6-CHECK-LOG
|
||||
-A ICMPV6-CHECK -p icmpv6 -m hl ! --hl-eq 255 --icmpv6-type neighbor-solicitation -j ICMPV6-CHECK-LOG
|
||||
-A ICMPV6-CHECK -p icmpv6 -m hl ! --hl-eq 255 --icmpv6-type neighbor-advertisement -j ICMPV6-CHECK-LOG
|
||||
-A ICMPV6-CHECK-LOG -j LOG --log-prefix "ICMPV6-CHECK-LOG DROP "
|
||||
-A ICMPV6-CHECK-LOG -j DROP
|
||||
|
||||
COMMIT
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
set -ex
|
||||
|
||||
DEPLOY_ARGS="server_ip=$LXC_IP server_user=root IP_subject_alt_name=$LXC_IP local_dns=Y"
|
||||
|
||||
|
@ -8,5 +8,5 @@ if [ "${LXC_NAME}" == "docker" ]
|
|||
then
|
||||
docker run -it -v $(pwd)/config.cfg:/algo/config.cfg -v ~/.ssh:/root/.ssh -e "DEPLOY_ARGS=${DEPLOY_ARGS}" travis/algo /bin/sh -c "chown -R 0:0 /root/.ssh && source env/bin/activate && ansible-playbook deploy.yml -t local,vpn,dns,ssh_tunneling,security,tests -e \"${DEPLOY_ARGS}\""
|
||||
else
|
||||
ansible-playbook deploy.yml -t local,vpn,dns,ssh_tunneling,tests -e "${DEPLOY_ARGS}"
|
||||
ansible-playbook deploy.yml -t local,vpn,dns,ssh_tunneling,tests -e "${DEPLOY_ARGS}" -vvvv
|
||||
fi
|
||||
|
|
Loading…
Add table
Reference in a new issue