Compare commits
31 commits
master
...
grevelle/m
Author | SHA1 | Date | |
---|---|---|---|
![]() |
afb48421c8 | ||
![]() |
204abbe605 | ||
![]() |
490191aca1 | ||
![]() |
5e74390abb | ||
![]() |
d1e36a8f6f | ||
![]() |
cc192dcf7f | ||
![]() |
302477544d | ||
![]() |
3a73f7c43f | ||
![]() |
a5c103fd5c | ||
![]() |
1e8fd51835 | ||
![]() |
91e50a2403 | ||
![]() |
95266a258d | ||
![]() |
0c5a3da28f | ||
![]() |
cf0555f07e | ||
![]() |
db2ffe6a10 | ||
![]() |
f6fe73ea8a | ||
![]() |
3e164750e8 | ||
![]() |
861248554b | ||
![]() |
5baec46e10 | ||
![]() |
8a057af98e | ||
![]() |
a2acf2825a | ||
![]() |
66783e9c43 | ||
![]() |
e152ea3540 | ||
![]() |
c65b9c23a6 | ||
![]() |
de66cd7653 | ||
![]() |
5383f20a58 | ||
![]() |
96d7054889 | ||
![]() |
4a17fc8675 | ||
![]() |
d6182d7bc3 | ||
![]() |
cb16a1932a | ||
![]() |
f71b21f5a0 |
7 changed files with 167 additions and 581 deletions
245
README.md
245
README.md
|
@ -1,103 +1,78 @@
|
||||||
# About
|
# About
|
||||||
|
|
||||||
This repository includes my notes on enabling a true bridge mode setup with AT&T U-Verse and pfSense. This method utilizes [netgraph](https://www.freebsd.org/cgi/man.cgi?netgraph(4)) which is a graph based kernel networking subsystem of FreeBSD. This low-level solution was required to account for the unique issues surrounding bridging 802.1X traffic and tagging a VLAN with an id of 0. I've tested and confirmed this setup works with AT&T U-Verse Internet on the ARRIS NVG589, NVG599 and BGW210-700 residential gateways (probably others too). For Pace 5268AC see special details below.
|
This repository allows bypassing the AT&T U-Verse fiber gateway using pfSense. This method utilizes [netgraph](https://www.freebsd.org/cgi/man.cgi?netgraph) which is a graph-based kernel networking subsystem of FreeBSD. This low-level solution was required to account for the unique issues surrounding bridging 802.1X traffic and tagging a VLAN with an id of 0. I've tested and confirmed this setup works with AT&T U-Verse Internet on the BGW210-700 residential gateway. It probably works with others too.
|
||||||
|
|
||||||
There are a few other methods to accomplish true bridge mode, so be sure to see what easiest for you. True Bridge Mode is also possible in a Linux via ebtables or using hardware with a VLAN swap trick. For me, I was not using a Linux-based router and the VLAN swap did not seem to work for me.
|
The netgraph method will allow you to fully utilize your own router and fully bypass your residential gateway. It survives reboots, re-authentications, IPv6 and new DHCP leases.
|
||||||
|
|
||||||
While many AT&T residential gateways offer something called _IP Passthrough_, it does not provide the same advantages of a true bridge mode. For example, the NAT table is still managed by the gateway, which is limited to a measly 8192 sessions (although it becomes unstable at even 60% capacity).
|
# Bypass Procedure
|
||||||
|
|
||||||
The netgraph method will allow you to fully utilize your own router and fully bypass your residential gateway. It survives reboots, re-authentications, IPv6, and new DHCP leases.
|
|
||||||
|
|
||||||
# How it Works
|
|
||||||
|
|
||||||
Before continuing to the setup, it's important to understand how this method works. This will make configuration and troubleshooting much easier.
|
|
||||||
|
|
||||||
## Standard Procedure
|
|
||||||
|
|
||||||
First, let's talk about what happens in the standard setup (without any bypass). At a high level, the following process happens when the gateway boots up:
|
|
||||||
|
|
||||||
1. All traffic on the ONT is protected with [802.1/X](https://en.wikipedia.org/wiki/IEEE_802.1X). So in order to talk to anything, the Router Gateway must first perform the [authentication procedure](https://en.wikipedia.org/wiki/IEEE_802.1X#Typical_authentication_progression). This process uses a unique certificate that is hardcoded on your residential gateway.
|
|
||||||
2. Once the authentication completes, you'll be able to properly "talk" to the outside. However, all of your traffic will need to be tagged with VLAN ID 0 (a.k.a. VLAN Priority Tagging<sup>[[1]](https://wikipedia.org/wiki/IEEE_802.1Q#Frame_format)[[2]](https://www.cisco.com/c/en/us/td/docs/switches/connectedgrid/cg-switch-sw-master/software/configuration/guide/vlan0/b_vlan_0.html)</sup>) before the IP gateway will respond.
|
|
||||||
3. Once traffic is tagged with VLAN0, your residential gateway needs to request a public IPv4 address via DHCP. The MAC address in the DHCP request needs to match that of the MAC address that's assigned to your AT&T account. Other than that, there's nothing special about the DCHPv4 handshake.
|
|
||||||
4. After the DHCP lease is issued, the WAN setup is complete. Your LAN traffic is then NAT'd and routed to the outside.
|
|
||||||
|
|
||||||
## Bypass Procedure
|
|
||||||
|
|
||||||
To bypass the gateway using pfSense, we can emulate the standard procedure. If we connect our Residential Gateway and ONT to our pfSense box, we can bridge the 802.1/X authentication sequence, tag our WAN traffic as VLAN0, and request a public IPv4 via DHCP using a spoofed MAC address.
|
|
||||||
|
|
||||||
Unfortunately, there are some challenges with emulating this process. First, it's against RFC to bridge 802.1/X traffic and it is not supported. Second, tagging traffic as VLAN0 is not supported through the standard interfaces.
|
|
||||||
|
|
||||||
This is where netgraph comes in. Netgraph allows you to break some rules and build the proper plumbing to make this work. So, our cabling looks like this:
|
|
||||||
|
|
||||||
```
|
|
||||||
Residential Gateway
|
|
||||||
[ONT Port]
|
|
||||||
|
|
|
||||||
|
|
|
||||||
[nic0] pfSense [nic1]
|
|
||||||
|
|
|
||||||
|
|
|
||||||
[ONT]
|
|
||||||
Outside
|
|
||||||
```
|
|
||||||
|
|
||||||
With netgraph, our procedure looks like this (at a high level):
|
|
||||||
|
|
||||||
1. The Residential Gateway initiates a 802.1/X EAPOL-START.
|
|
||||||
1. The packet then is bridged through netgraph to the ONT interface.
|
|
||||||
1. If the packet matches an 802.1/X type (which is does), it is passed to the ONT interface. If it does not, the packet is discarded. This prevents our Residential Gateway from initiating DHCP. We want pfSense to handle that.
|
|
||||||
1. The ONT should then see and respond to the EAPOL-START, which is passed back through our netgraph back to the residential gateway. At this point, the 802.1/X authentication should be complete.
|
|
||||||
1. netgraph has also created an interface for us called `ngeth0`. This interface is connected to `ng_vlan` which is configured to tag all traffic as VLAN0 before sending it on to the ONT interface.
|
|
||||||
1. pfSense can then be configured to use `ngeth0` as the WAN interface.
|
|
||||||
1. Next, we spoof the MAC address of the residential gateway and request a DHCP lease on `ngeth0`. The packets get tagged as VLAN0 and exit to the ONT.
|
|
||||||
1. Now the DHCP handshake should complete and we should be on our way!
|
|
||||||
|
|
||||||
Hopefully, that now gives you an idea of what we are trying to accomplish. See the comments and commands `bin/pfatt.sh` for details about the netgraph setup.
|
|
||||||
|
|
||||||
But enough talk. Now for the fun part!
|
|
||||||
|
|
||||||
# Setup
|
|
||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
* At least __three__ physical network interfaces on your pfSense server
|
|
||||||
* The MAC address of your Residential Gateway
|
|
||||||
* Local or console access to pfSense
|
* Local or console access to pfSense
|
||||||
* pfSense 2.4.5 running on amd64 architecture _(If you are running pfSense 2.4.4 please see instruction in the [Before-pfSense-2.4.5 branch](https://github.com/MonkWho/pfatt/blob/Before-pfSense-2.4.5/README.md))_
|
* pfSense 2.5.1+ running on amd64 architecture
|
||||||
|
* Two physical network interfaces on your pfSense server
|
||||||
|
* The MAC address of your EAP-TLS Identity (from residential gateway used for certificates)
|
||||||
|
* Valid certificates to perform EAP-TLS authentication (see Extracting Certificates)
|
||||||
|
|
||||||
At this time there is a bug in pFsense 2.4.5 and [ng_etf module is only included in pFsense 2.4.5 _amd64 build_](
|
## Notes
|
||||||
https://redmine.pfsense.org/issues/10463). Should be fixed in 2.4.5-p1.
|
|
||||||
|
|
||||||
PFSense Builds for Netgate hardware may not include ng_etf (Confimred on SG4860-Desktop 2.4.5-p1). Confirm ng_etf exists before continuing and look at [Before-pfSense-2.4.5 branch](https://github.com/MonkWho/pfatt/blob/Before-pfSense-2.4.5/README.md) for gudiance if it doesn't exist.
|
If you have valid certs that have been extracted from an authorized residential gateway device, you can utilize the native wpa_supplicant client in pfSense to perform 802.1X EAP-TLS authentication.
|
||||||
|
|
||||||
If you are running pfSense on anything other than amd64 architecture you should compile your own version of ng_etf. Look at [Before-pfSense-2.4.5 branch](https://github.com/MonkWho/pfatt/blob/Before-pfSense-2.4.5/README.md) for some guidance on compiling and running your own ng_etf.
|
Note that EAP-TLS authentication authorizes the device, not the subscriber. Meaning, any authorized device (e.g., BGW210) can be used to authorize the link. It does not have to match the residential gateway assigned to your account. For example, a BGW210 purchased of eBay can authorize the link. The subscriber's service is authorized separately (probably by the DHCP MAC and/or ONT serial number).
|
||||||
|
|
||||||
If you only have two NICs, you can buy this cheap USB 100Mbps NIC [from Amazon](https://www.amazon.com/gp/product/B00007IFED) as your third. It has the Asix AX88772 chipset, which is supported in FreeBSD with the [axe](https://www.freebsd.org/cgi/man.cgi?query=axe&sektion=4) driver. I've confirmed it works in my setup. The driver was already loaded and I didn't have to install or configure anything to get it working. Also, don't worry about the poor performance of USB or 100Mbps NICs. This third NIC will only send/recieve a few packets periodicaly to authenticate your Router Gateway. The rest of your traffic will utilize your other (and much faster) NICs.
|
In supplicant mode, the residential gateway can be permanently disconnected. We will use netgraph to tag our traffic with VLAN0 and spoof the MAC address from the residential gateway.
|
||||||
|
|
||||||
## Install
|
## High Level Steps
|
||||||
|
|
||||||
1. Edit the following configuration variables in `bin/pfatt.sh` as noted below. `$RG_ETHER_ADDR` should match the MAC address of your Residential Gateway. AT&T will only grant a DHCP lease to the MAC they assigned your device. In my environment, it's:
|
Before continuing to the setup, it's important to understand how this method works. This will make configuration and troubleshooting much easier.
|
||||||
|
|
||||||
|
1. Netgraph creates an interface for us called ngeth0. This interface is connected to vlan0 which is configured to tag all traffic as VLAN0 before sending it on to the ONT interface.
|
||||||
|
2. wpa_supplicant binds to ngeth0 and initiates 802.1X EAP-TLS authentication
|
||||||
|
3. pfSense can then be configured to use ngeth0 as the WAN interface.
|
||||||
|
4. Spoof the MAC address of the residential gateway and request a DHCP lease on ngeth0. The packets get tagged as VLAN0 and exit to the ONT.
|
||||||
|
5. Now the DHCP handshake should complete and we should be on our way!
|
||||||
|
|
||||||
|
See the comments and commands bin/pfatt.sh for details about the netgraph setup.
|
||||||
|
|
||||||
|
## Detailed Steps
|
||||||
|
|
||||||
|
1. Edit the following configuration variables in `bin/pfatt.sh` as noted below. `$RG_ETHER_ADDR` should match the MAC address of your Residential Gateway. AT&T will only grant a DHCP lease to the MAC they assigned your device.
|
||||||
```shell
|
```shell
|
||||||
ONT_IF='xx0' # NIC -> ONT / Outside
|
ONT_IF='xx0' # NIC -> ONT / Outside
|
||||||
RG_IF='xx1' # NIC -> Residential Gateway's ONT port
|
|
||||||
RG_ETHER_ADDR='xx:xx:xx:xx:xx:xx' # MAC address of Residential Gateway
|
RG_ETHER_ADDR='xx:xx:xx:xx:xx:xx' # MAC address of Residential Gateway
|
||||||
|
CA_PEM='xxx.pem' # Replace xxx with file name of gateway certificate
|
||||||
|
CLIENT_PEM='xxx.pem' # Replace xxx with file name of gateway certificate
|
||||||
|
PRIVATE_PEM='xxx.pem' # Replace xxx with file name of gateway certificate
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Copy `bin/pfatt.sh` to `/root/bin` (or any directory):
|
2. Copy `bin/pfatt.sh` to `/root/bin` (or any directory) and make executable:
|
||||||
```
|
```
|
||||||
ssh root@pfsense mkdir /root/bin
|
ssh root@pfsense mkdir /root/bin
|
||||||
scp bin/pfatt.sh root@pfsense:/root/bin/
|
scp bin/pfatt.sh root@pfsense:/root/bin/
|
||||||
ssh root@pfsense chmod +x /root/bin/pfatt.sh
|
ssh root@pfsense chmod +x /root/bin/pfatt.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
**NOTE:** If you have the 5268AC, you'll also need to install `pfatt-5268AC-startup.sh` and `pfatt-5268.sh`. The scripts monitor your connection and disable or enable the EAP bridging as needed. It's a hacky workaround, but it enables you to keep your 5268AC connected, avoid EAP-Logoffs and survive reboots. Consider changing the `PING_HOST` in `pfatt-5268AC.sh` to a reliable host. Then perform these additional steps to install:
|
3. Extracting Certificates:
|
||||||
```
|
Certificates can be extracted by the exploitation of the residential gateway to get a root shell. Here are instructions to do so in windows by [iwleonards](https://github.com/iwleonards/extract-mfg).
|
||||||
scp bin/pfatt-5268AC-startup.sh root@pfsense:/usr/local/etc/rc.d/pfatt-5268AC-startup.sh
|
|
||||||
scp bin/pfatt-5268AC.sh root@pfsense:/root/bin/
|
|
||||||
ssh root@pfsense chmod +x /usr/local/etc/rc.d/pfatt-5268AC-startup.sh /root/bin/pfatt-5268AC.sh
|
|
||||||
```
|
|
||||||
|
|
||||||
3. To start pfatt.sh script at the beginning of the boot process pfSense team recomments you use a package called shellcmd. Use pfSense package installer to find and install it. Once you have shellcmd package installed you can find it in Services > Shellcmd. Now add a new command and fill it up accordingly (make sure to select earlyshellcmd from a dropdown):
|
Be careful, you have sole responsibility for not bricking your residential gateway.
|
||||||
|
|
||||||
|
In case they are needed, here are firmware archives:
|
||||||
|
* [1.0.29 Firmware](https://drive.google.com/file/d/1VYxpTu9m3cLIv8vCTzs_ccFAblJjH8c0/view?usp=sharing)
|
||||||
|
* [Firmware archive](https://drive.google.com/file/d/1AcP3gbjpZOsnGTFApQOlalLzpjidUDj4/view?usp=drivesdk)
|
||||||
|
|
||||||
|
4. Upload your extracted certs (see Extracting Certificates) to /conf/pfatt/wpa. You should have three files in the wpa directory as such. You may also need to match the permissions. Do this with `sudo chmod -R 0600 /conf/pfatt/wpa`
|
||||||
|
```
|
||||||
|
[2.5.2-RELEASE][root@pfsense.knox.lan]/conf/pfatt/wpa: ls -al
|
||||||
|
total 19
|
||||||
|
drwxr-xr-x 2 root wheel 5 Jan 10 16:32 .
|
||||||
|
drwxr-xr-x 4 root wheel 5 Jan 10 16:33 ..
|
||||||
|
-rw------- 1 root wheel 5150 Jan 10 16:32 ca.pem
|
||||||
|
-rw------- 1 root wheel 1123 Jan 10 16:32 client.pem
|
||||||
|
-rw------- 1 root wheel 887 Jan 10 16:32 private.pem
|
||||||
|
```
|
||||||
|
|
||||||
|
5. To start pfatt.sh script at the beginning of the boot process pfSense team recommends you use a package called shellcmd. Use pfSense package installer to find and install it. Once you have shellcmd package installed you can find it in Services > Shellcmd. Now add a new command and fill it up accordingly (make sure to select earlyshellcmd from a dropdown):
|
||||||
```
|
```
|
||||||
Command: /root/bin/pfatt.sh
|
Command: /root/bin/pfatt.sh
|
||||||
Shellcmd Type: earlyshellcmd
|
Shellcmd Type: earlyshellcmd
|
||||||
|
@ -105,17 +80,19 @@ If you only have two NICs, you can buy this cheap USB 100Mbps NIC [from Amazon](
|
||||||
It should look like this:
|
It should look like this:
|
||||||

|

|
||||||
|
|
||||||
This can also be acomplished by manually editing your pfSense /conf/config.xml file. Add <earlyshellcmd>/root/bin/pfatt.sh</earlyshellcmd> above </system>. This method is not recommended and is frowned upon by pfSense team.
|
This can also be accomplished by manually editing your pfSense /conf/config.xml file. Add <earlyshellcmd>/root/bin/pfatt.sh</earlyshellcmd> above. This method is not recommended and is frowned upon by pfSense team.
|
||||||
|
|
||||||
4. Connect cables:
|
6. Connect cables:
|
||||||
- `$RG_IF` to Residential Gateway on the ONT port (not the LAN ports!)
|
|
||||||
- `$ONT_IF` to ONT (outside)
|
- `$ONT_IF` to ONT (outside)
|
||||||
- `LAN NIC` to local switch (as normal)
|
- `LAN NIC` to local switch (as normal)
|
||||||
|
|
||||||
5. Prepare for console access.
|
7. Prepare for console access.
|
||||||
6. Reboot.
|
|
||||||
7. pfSense will detect new interfaces on bootup. Follow the prompts on the console to configure `ngeth0` as your pfSense WAN. Your LAN interface should not normally change. However, if you moved or re-purposed your LAN interface for this setup, you'll need to re-apply any existing configuration (like your VLANs) to your new LAN interface. pfSense does not need to manage `$RG_IF` or `$ONT_IF`. I would advise not enabling those interfaces in pfSense as it can cause problems with the netgraph.
|
8. Reboot.
|
||||||
8. In the webConfigurator, configure the WAN interface (`ngeth0`) to DHCP using the MAC address of your Residential Gateway.
|
|
||||||
|
9. pfSense will detect new interfaces on bootup. Follow the prompts on the console to configure `ngeth0` as your pfSense WAN. Your LAN interface should not normally change. However, if you moved or re-purposed your LAN interface for this setup, you'll need to re-apply any existing configuration (like your VLANs) to your new LAN interface. pfSense does not need to manage `$ONT_IF`. I would advise not enabling those interfaces in pfSense as it can cause problems with the netgraph.
|
||||||
|
|
||||||
|
10. In the webConfigurator, configure the WAN interface (`ngeth0`) to DHCP using the MAC address of your Residential Gateway.
|
||||||
|
|
||||||
If everything is setup correctly, netgraph should be bridging EAP traffic between the ONT and RG, tagging the WAN traffic with VLAN0, and your WAN interface configured with an IPv4 address via DHCP.
|
If everything is setup correctly, netgraph should be bridging EAP traffic between the ONT and RG, tagging the WAN traffic with VLAN0, and your WAN interface configured with an IPv4 address via DHCP.
|
||||||
|
|
||||||
|
@ -123,7 +100,7 @@ If everything is setup correctly, netgraph should be bridging EAP traffic betwee
|
||||||
|
|
||||||
Once your netgraph setup is in place and working, there aren't any netgraph changes required to the setup to get IPv6 working. These instructions can also be followed with a different bypass method other than the netgraph method. Big thanks to @pyrodex1980's [post](http://www.dslreports.com/forum/r32118263-) on DSLReports for sharing your notes.
|
Once your netgraph setup is in place and working, there aren't any netgraph changes required to the setup to get IPv6 working. These instructions can also be followed with a different bypass method other than the netgraph method. Big thanks to @pyrodex1980's [post](http://www.dslreports.com/forum/r32118263-) on DSLReports for sharing your notes.
|
||||||
|
|
||||||
This setup assumes you have a fairly recent version of pfSense. I'm using 2.4.5.
|
This setup assumes you have a fairly recent version of pfSense. I'm using 2.5.2.
|
||||||
|
|
||||||
**DUID Setup**
|
**DUID Setup**
|
||||||
|
|
||||||
|
@ -178,22 +155,11 @@ Output from `pfatt.sh` and `pfatt-5268AC.sh` can be found in `/var/log/pfatt.log
|
||||||
|
|
||||||
## tcpdump
|
## tcpdump
|
||||||
|
|
||||||
Use tcpdump to watch the authentication, vlan and dhcp bypass process (see above). Run tcpdumps on the `$ONT_IF` interface and the `$RG_IF` interface:
|
Use tcpdump to watch the authentication, vlan and dhcp bypass process (see above). Run tcpdumps on the `$ONT_IF` interface:
|
||||||
```
|
```
|
||||||
tcpdump -ei $ONT_IF
|
tcpdump -ei $ONT_IF
|
||||||
tcpdump -ei $RG_IF
|
|
||||||
```
|
```
|
||||||
|
You should see some more EAP packets from the `$ONT_IF` interface as it negotiates 802.1/X EAP authentication.
|
||||||
Restart your Residential Gateway. From the `$RG_IF` interface, you should see some EAPOL starts like this:
|
|
||||||
```
|
|
||||||
MAC (oui Unknown) > MAC (oui Unknown), ethertype EAPOL (0x888e), length 60: POL start
|
|
||||||
```
|
|
||||||
|
|
||||||
If you don't see these, make sure you're connected to the ONT port.
|
|
||||||
|
|
||||||
These packets come every so often. I think the RG does some backoff / delay if doesn't immediately auth correctly. You can always reboot your RG to initiate the authentication again.
|
|
||||||
|
|
||||||
If your netgraph is setup correctly, the EAP start packet from the `$RG_IF` will be bridged onto your `$ONT_IF` interface. Then you should see some more EAP packets from the `$ONT_IF` interface and `$RG_IF` interface as they negotiate 802.1/X EAP authentication.
|
|
||||||
|
|
||||||
Once that completes, watch `$ONT_IF` and `ngeth0` for DHCP traffic.
|
Once that completes, watch `$ONT_IF` and `ngeth0` for DHCP traffic.
|
||||||
```
|
```
|
||||||
|
@ -211,7 +177,7 @@ If you don't see traffic being bridged between `ngeth0` and `$ONT_IF`, then netg
|
||||||
|
|
||||||
## Promiscuous Mode
|
## Promiscuous Mode
|
||||||
|
|
||||||
`pfatt.sh` will put `$RG_IF` in promiscuous mode via `/sbin/ifconfig $RG_IF promisc`. Otherwise, the EAP packets would not bridge. I think this is necessary for everyone but I'm not sure. Turn it off if it's causing issues.
|
`pfatt.sh` will put `$ONT_IF` in promiscuous mode via `/sbin/ifconfig $ONT_IF promisc`. I think this is necessary for everyone but I'm not sure. Turn it off if it's causing issues.
|
||||||
|
|
||||||
## netgraph
|
## netgraph
|
||||||
|
|
||||||
|
@ -219,9 +185,7 @@ The netgraph system provides a uniform and modular system for the implementation
|
||||||
|
|
||||||
Your netgraph should look something like this:
|
Your netgraph should look something like this:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
In this setup, the `ue0` interface is my `$RG_IF` and the `bce0` interface is my `$ONT_IF`. You can generate your own graphviz via `ngctl dot`. Copy the output and paste it at [webgraphviz.com](http://www.webgraphviz.com/).
|
|
||||||
|
|
||||||
Try these commands to inspect whether netgraph is configured properly.
|
Try these commands to inspect whether netgraph is configured properly.
|
||||||
|
|
||||||
|
@ -236,101 +200,30 @@ Try these commands to inspect whether netgraph is configured properly.
|
||||||
2. Issue `ngctl list` to list netgraph nodes. Inspect `pfatt.sh` to verify the netgraph output matches the configuration in the script. It should look similar to this:
|
2. Issue `ngctl list` to list netgraph nodes. Inspect `pfatt.sh` to verify the netgraph output matches the configuration in the script. It should look similar to this:
|
||||||
```
|
```
|
||||||
$ ngctl list
|
$ ngctl list
|
||||||
There are 9 total nodes:
|
There are 5 total nodes:
|
||||||
Name: o2m Type: one2many ID: 000000a0 Num hooks: 3
|
|
||||||
Name: vlan0 Type: vlan ID: 000000a3 Num hooks: 2
|
Name: vlan0 Type: vlan ID: 000000a3 Num hooks: 2
|
||||||
Name: ngeth0 Type: eiface ID: 000000a6 Num hooks: 1
|
Name: ngeth0 Type: eiface ID: 000000a6 Num hooks: 1
|
||||||
Name: <unnamed> Type: socket ID: 00000006 Num hooks: 0
|
Name: <unnamed> Type: socket ID: 00000006 Num hooks: 0
|
||||||
Name: ngctl28740 Type: socket ID: 000000ca Num hooks: 0
|
Name: ngctl28740 Type: socket ID: 000000ca Num hooks: 0
|
||||||
Name: waneapfilter Type: etf ID: 000000aa Num hooks: 2
|
|
||||||
Name: laneapfilter Type: etf ID: 000000ae Num hooks: 3
|
|
||||||
Name: bce0 Type: ether ID: 0000006e Num hooks: 1
|
Name: bce0 Type: ether ID: 0000006e Num hooks: 1
|
||||||
Name: ue0 Type: ether ID: 00000016 Num hooks: 2
|
|
||||||
```
|
|
||||||
3. Inspect the various nodes and hooks. Example for `ue0`:
|
|
||||||
```
|
|
||||||
$ ngctl show ue0:
|
|
||||||
Name: ue0 Type: ether ID: 00000016 Num hooks: 2
|
|
||||||
Local hook Peer name Peer type Peer ID Peer hook
|
|
||||||
---------- --------- --------- ------- ---------
|
|
||||||
upper laneapfilter etf 000000ae nomatch
|
|
||||||
lower laneapfilter etf 000000ae downstream
|
|
||||||
```
|
```
|
||||||
|
3. Inspect the various nodes and hooks.
|
||||||
|
|
||||||
### Reset netgraph
|
## Reset netgraph
|
||||||
|
|
||||||
`pfatt.sh` expects a clean netgraph before it can be ran. To reset a broken netgraph state, try this:
|
`pfatt.sh` expects a clean netgraph before it can be ran. To reset a broken netgraph state, try this:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
/usr/sbin/ngctl shutdown waneapfilter:
|
|
||||||
/usr/sbin/ngctl shutdown laneapfilter:
|
|
||||||
/usr/sbin/ngctl shutdown $ONT_IF:
|
/usr/sbin/ngctl shutdown $ONT_IF:
|
||||||
/usr/sbin/ngctl shutdown $RG_IF:
|
|
||||||
/usr/sbin/ngctl shutdown o2m:
|
|
||||||
/usr/sbin/ngctl shutdown vlan0:
|
/usr/sbin/ngctl shutdown vlan0:
|
||||||
/usr/sbin/ngctl shutdown ngeth0:
|
/usr/sbin/ngctl shutdown ngeth0:
|
||||||
```
|
```
|
||||||
|
|
||||||
## pfSense
|
## pfSense
|
||||||
|
|
||||||
In some circumstances, pfSense may alter your netgraph. This is especially true if pfSense manages either your `$RG_IF` or `$ONT_IF`. If you make some interface changes and your connection breaks, check to see if your netgraph was changed.
|
In some circumstances, pfSense may alter your netgraph. This is especially true if pfSense manages either your `$ONT_IF`. If you make some interface changes and your connection breaks, check to see if your netgraph was changed.
|
||||||
|
|
||||||
# Virtualization Notes
|
|
||||||
|
|
||||||
This setup has been tested on physical servers and virtual machines. Virtualization adds another layer of complexity for this setup, and will take extra consideration.
|
|
||||||
|
|
||||||
## QEMU / KVM / Proxmox
|
|
||||||
|
|
||||||
Proxmox uses a bridged networking model, and thus utilizes Linux's native bridge capability. To use this netgraph method, you do a PCI passthrough for the `$RG_IF` and `$ONT_IF` NICs. The bypass procedure should then be the same.
|
|
||||||
|
|
||||||
You can also solve the EAP/802.1X and VLAN0/802.1Q problem by setting the `group_fwd_mask` and creating a vlan0 interface to bridge to your VM. See *Other Methods* below.
|
|
||||||
|
|
||||||
## ESXi
|
|
||||||
|
|
||||||
I haven't tried to do this with ESXi. Feel free to submit a PR with notes on your experience. PCI passthrough is probably the best approach here though.
|
|
||||||
|
|
||||||
# Other Methods
|
|
||||||
|
|
||||||
## Linux
|
|
||||||
|
|
||||||
If you're looking how to do this on a Linux-based router, please refer to [this method](http://blog.0xpebbles.org/Bypassing-At-t-U-verse-hardware-NAT-table-limits) which utilizes ebtables and some kernel features. The method is well-documented there and I won't try to duplicate it. This method is generally more straight forward than doing this on BSD. However, please submit a PR for any additional notes for running on Linux routers.
|
|
||||||
|
|
||||||
## VLAN Swap
|
|
||||||
|
|
||||||
There is a whole thread on this at [DSLreports](http://www.dslreports.com/forum/r29903721-AT-T-Residential-Gateway-Bypass-True-bridge-mode). The gist of this method is that you connect your ONT, RG and WAN to a switch. Create two VLANs. Assign the ONT and RG to VLAN1 and the WAN to VLAN2. Let the RG authenticate, then change the ONT VLAN to VLAN2. The WAN the DHCPs and your in business.
|
|
||||||
|
|
||||||
However, I don't think this works for everyone. I had to explicitly tag my WAN traffic to VLAN0 which wasn't supported on my switch.
|
|
||||||
|
|
||||||
## OPNSense / FreeBSD
|
|
||||||
For OPNSense 20.1:
|
|
||||||
follow the pfSense instructions, EXCEPT:
|
|
||||||
1) use file opnatt.sh
|
|
||||||
2) do *NOT* install the ng_etf.ko, as OPNSense already has this module installed.
|
|
||||||
3) put the opnatt.sh script into `/usr/local/etc/rc.syshook.d/early` as `99-opnatt.sh`
|
|
||||||
4) do *NOT* modify config.xml, nor do any of the duid stuff
|
|
||||||
5) note: You *CAN* use IPv6 Prefix id 0, as OPNSense does *NOT* assign a routeable IPv6 address to ngeth0
|
|
||||||
|
|
||||||
I haven't tried this with native FreeBSD, but I imagine the process is ultimately the same with netgraph. Feel free to submit a PR with notes on your experience.
|
|
||||||
|
|
||||||
# U-verse TV
|
|
||||||
|
|
||||||
See [U-VERSE_TV.md](U-VERSE_TV.md)
|
|
||||||
|
|
||||||
# References
|
|
||||||
|
|
||||||
- http://blog.0xpebbles.org/Bypassing-At-t-U-verse-hardware-NAT-table-limits
|
|
||||||
- https://forum.netgate.com/topic/99190/att-uverse-rg-bypass-0-2-btc/
|
|
||||||
- http://www.dslreports.com/forum/r29903721-AT-T-Residential-Gateway-Bypass-True-bridge-mode
|
|
||||||
- https://www.dslreports.com/forum/r32127305-True-Bridge-mode-on-pfSense-with-netgraph
|
|
||||||
- https://www.dslreports.com/forum/r32116977-AT-T-Fiber-RG-Bypass-pfSense-IPv6
|
|
||||||
- http://www.netbsd.org/gallery/presentations/ast/2012_AsiaBSDCon/Tutorial_NETGRAPH.pdf
|
|
||||||
|
|
||||||
# Credits
|
# Credits
|
||||||
|
|
||||||
This took a lot of testing and a lot of hours to figure out. A unique solution was required for this to work in pfSense. If this helped you out, please buy us a coffee.
|
- [aus](https://github.com/aus) - 31m9ujhbsRRZs4S64njEkw8ksFSTTDcsRU - For the original work
|
||||||
|
- [iwleonards](https://github.com/iwleonards/extract-mfg) - Residential gateway certificate extraction
|
||||||
- [rajl](https://forum.netgate.com/user/rajl) - for the netgraph idea - 1H8CaLNXembfzYGDNq1NykWU3gaKAjm8K5
|
|
||||||
- [pyrodex](https://www.dslreports.com/profile/1717952) - for IPv6 - ?
|
|
||||||
- [aus](https://github.com/aus) - 31m9ujhbsRRZs4S64njEkw8ksFSTTDcsRU
|
|
||||||
- [/u/MisterBazz](https://www.reddit.com/user/MisterBazz/) - [for the initial setup guide on U-verse TV documentation](https://www.reddit.com/r/PFSENSE/comments/ag43rb/att_bgw210_true_independent_bridge_mode_uverse/) that formed the basis for [U-VERSE_TV.md](U-VERSE_TV.md)
|
|
||||||
- [0xC0ncord](https://github.com/0xC0ncord) - for the [U-Verse TV Documentation](U-VERSE_TV.md)
|
|
||||||
|
|
176
U-VERSE_TV.md
176
U-VERSE_TV.md
|
@ -1,176 +0,0 @@
|
||||||
# U-verse TV
|
|
||||||
|
|
||||||
If you have a U-verse TV subscription, you will need to perform some additional setup in order to get it working with your new pfSense system in-line with the residential gateway (RG).
|
|
||||||
|
|
||||||
## Preface
|
|
||||||
|
|
||||||
This guide was intially written by [0xC0ncord](https://github.com/0xC0ncord) in conjunction with the setup detailed by [/u/MisterBazz](https://www.reddit.com/r/PFSENSE/comments/ag43rb/att_bgw210_true_independent_bridge_mode_uverse/) and my personal experience in getting this entire setup working properly. The reason why I am mentioning this is to ~~shamelessly credit myself~~ make note that [aus had previously stated he does not have a TV subscription](https://github.com/aus/pfatt/issues/3#issue-362961147) at the time of writing and that there may be a disconnect between my point of view and his. Therefore, I want to point out that this portion of the guide is a community effort, and if you run into any issues or need assistance even after [troubleshooting](#Troubleshooting), please do not be afraid to ask for support.
|
|
||||||
|
|
||||||
## Overview / Prerequisites
|
|
||||||
|
|
||||||
Bypassing your AT&T residential gateway (RG) for U-verse TV is mostly straightforward (albeit sometimes a pain) from here on, but there is one major consideration that needs to be addressed.
|
|
||||||
|
|
||||||
U-verse TV streams are received through both IPv4 unicast and multicast streams. When selecting a channel through the Digital Video Receiver (DVR), the DVR will request the channel video stream while simultaneously sending an IGMP membership report and will receive the unicast stream for approximately 10 seconds before seamlessly switching to multicast. The amount of bandwidth consumed by the digital video stream for TV in general is a force to be reckoned with, and depending on how you choose to proceed with the setup may introduce noticeable network degradation. Because of the way IPv4 multicast traffic operates, you will end up in a situation where digital video traffic is being propogated throughout your network in ways that may not be desireable.To quote [/u/MisterBazz](https://www.reddit.com/r/PFSENSE/comments/ag43rb/att_bgw210_true_independent_bridge_mode_uverse/) on where I obtained most of this documentation, "it is way easier to set up a whole separate U-verse LAN than to pump all of this through your switch and configure the switch appropriately. It also makes it easy in setting up firewall rules as well."
|
|
||||||
|
|
||||||
For this guide, there are two paths to take:
|
|
||||||
1. Isolate the DVR on its own internal network (recommended).
|
|
||||||
2. Keep the DVR on the same internal LAN.
|
|
||||||
|
|
||||||
The prerequisites and so forth for each of these are documented below in their respective sections. Personally, I chose to put the DVR in its own network and so I cannot say for sure whether not doing so would actually result in noticeable network degradation, but your mileage may vary depending on your setup.
|
|
||||||
|
|
||||||
In summary, these are the basic steps performed by the DVR when selecting a channel to watch:
|
|
||||||
1. The DVR requests the unicast stream and sends an IGMP membership report for the desired channel.
|
|
||||||
2. The DVR begins playing the unicast stream and waits for the multicast stream.
|
|
||||||
3. The DVR begins receiving the multicast stream and stops receiving the unicast stream after approximately 10 seconds of video output.
|
|
||||||
4. Periodically, the DVR receives an IGMP general membership query from AT&T's network and will respond with another IGMP membership report while the channel is still being watched.
|
|
||||||
|
|
||||||
If the DVR were to change channels, it sends an IGMP leave group message for the current channel and repeats the steps above for the new channel.
|
|
||||||
|
|
||||||
On a final note, you need to ensure that the U-verse TV DVR you have supports IP video input. At the time of writing, I was unable to find any documentation of any sort of U-verse DVR that did not support this, especially since the manuals for them did not explicitly say so. In my case, I had an AT&T/Motorola VIP 2250, which was previously receiving video via a coaxial cable plugged into the back of the residential gateway before doing this setup. The manual for this particular DVR documents the RJ45 port on the back of the device but states it is for output and says nothing about input. After a little Google-fu I just barely confirmed my suspicious that this port could also be used for video input, but your DVR may be different if you have a different model.
|
|
||||||
|
|
||||||
With all that mess out of the way, let's get started!
|
|
||||||
|
|
||||||
## Setup
|
|
||||||
|
|
||||||
Refer to the above two paths and pick whichever works for you.
|
|
||||||
|
|
||||||
### Isolate the DVR on its Own Internal Network (Recommended)
|
|
||||||
|
|
||||||
#### Prerequisites
|
|
||||||
|
|
||||||
Since we will be plugging the DVR more or less directly into your pfSense box, you will need an additional physical interface. If you followed the rest of the pfatt guide, this brings the total number of required interfaces to **4**. Obviously, this means you must also have a way to physically connect the RJ45 port on your DVR to the interface on your pfSense box. The coaxial port on your DVR will no longer be needed if you were using it previously.
|
|
||||||
|
|
||||||
#### Setup
|
|
||||||
|
|
||||||
1. Re-cable your DVR.
|
|
||||||
- Start by unplugging the coaxial cable from the back of the DVR if you are using it. You may as well unplug the coaxial cable from the back of your residential gateway as well.
|
|
||||||
- Connect your DVR to your pfSense box using the RJ45 port on the back next to the coaxial port.
|
|
||||||
2. Configure the UVerseDVR interface.
|
|
||||||
1. On pfSense, navigate to _Interfaces > Interface Assignments_
|
|
||||||
2. Under **Available network ports** find and add the interface you connected your DVR to. Take note of the name it is added as.
|
|
||||||
3. Navigate to the interface's configuration by going to _Interfaces > (Newly created interface)_
|
|
||||||
4. Change the interface's description to something more meaningful. I chose `UverseDVR`
|
|
||||||
5. Ensure that **Enable** is checked.
|
|
||||||
6. Set your pfSense's static IPv4 address for this new interface under **Static IPv4 Configuration**. This should be an RFC 1918 address that is not already in use on any other LAN in your network. You should also keep the size of the network relatively small. I chose `10.5.5.1/29`.
|
|
||||||
7. Hit **Save**
|
|
||||||
3. Configure the DHCP server on the DVR interface.
|
|
||||||
1. Navigate to _Services > DHCP Server_
|
|
||||||
2. Select the DVR interface tab.
|
|
||||||
3. Check **Enable**
|
|
||||||
4. Configure the DHCP address range in **Range**. Make sure this range is inside the network you allocated in step 2-6. I chose `10.5.5.2` - `10.5.5.5`
|
|
||||||
5. Enter AT&T's DNS servers in **DNS Servers** (optional but highly recommended):
|
|
||||||
- `68.94.156.1`
|
|
||||||
- `68.94.157.1`
|
|
||||||
(These may be different depending on your location)
|
|
||||||
6. Hit **Save**
|
|
||||||
4. Configure the IGMP Proxy.
|
|
||||||
1. Navigate to _Services > IGMP Proxy_
|
|
||||||
2. Check **Enable IGMP**
|
|
||||||
3. Click **Add**
|
|
||||||
4. Select your WAN interface under **Interface**
|
|
||||||
5. Enter a meaningful description if you so choose. I used `U-verse IPTV`
|
|
||||||
6. Set **Type** to `Upstream interface`
|
|
||||||
7. For _Networks_, enter `0.0.0.1/1`
|
|
||||||
8. Hit **Save**
|
|
||||||
9. Click **Add**
|
|
||||||
10. Select your DVR interface under **Interface**
|
|
||||||
11. Enter a meaningful description if you so choose. I used `U-verse IPTV`
|
|
||||||
12. Set **Type** to `Downstream interface`
|
|
||||||
13. For **Networks**, enter the network you created in step 2-6. I chose `10.5.5.0/29`
|
|
||||||
14. Hit **Save**
|
|
||||||
5. Configure the firewall.
|
|
||||||
1. Navigate to _Firewall > Rules_
|
|
||||||
2. Select the _Floating_ tab.
|
|
||||||
3. Create a rule as follows:
|
|
||||||
- **Action**: `Pass`
|
|
||||||
- **Quick**: `Checked`
|
|
||||||
- **Interface**: `WAN, UverseDVR`
|
|
||||||
- **Protocol**: `Any`
|
|
||||||
- **Destination**: `Network` `224.0.0.0/8`
|
|
||||||
- **Description**: `Allow multicast to U-verse IPTV`
|
|
||||||
- **Allow IP options**: `Checked`
|
|
||||||
4. Create another rule as follows:
|
|
||||||
- **Action**: `Pass`
|
|
||||||
- **Quick**: `Checked`
|
|
||||||
- **Interface**: `WAN, UverseDVR`
|
|
||||||
- **Protocol**: `Any`
|
|
||||||
- **Destination**: `Network` `239.0.0.0/8`
|
|
||||||
- **Description**: `Allow multicast to U-verse IPTV`
|
|
||||||
- **Allow IP options**: `Checked`
|
|
||||||
5. Save and apply your new rules.
|
|
||||||
|
|
||||||
If you made it this far your new setup should be complete!
|
|
||||||
|
|
||||||
### Keep the DVR on the Same Internal LAN
|
|
||||||
|
|
||||||
#### Prerequisites
|
|
||||||
|
|
||||||
If you were previously using the coaxial port on your DVR to connect it to your residential gateway, you will need to now connect your DVR to your LAN using the RJ45 next to it. The coaxial port on your DVR will no longer be needed if you were using it.
|
|
||||||
|
|
||||||
#### Setup
|
|
||||||
1. Re-cable your DVR.
|
|
||||||
- Start by unplugging the coaxial cable from the back of the DVR if you are using it. You may as well unplug the coaxial cable from the back of your residential gateway as well.
|
|
||||||
- Connect your DVR to your LAN using the RJ45 port on the back next to the coaxial port.
|
|
||||||
2. Create a static DHCP lease for the DVR.
|
|
||||||
1. Go to _Services > DHCP Server > LAN_
|
|
||||||
2. Under **DHCP Static Mappings for this Interface** choose **Add**
|
|
||||||
3. Enter your DVR's MAC address in **MAC Address**
|
|
||||||
4. Assign some IP address to the DVR in **IP Address**. It **must** be an IPv4 address.
|
|
||||||
5. Enter AT&T's DNS servers in **DNS Servers** (optional but highly recommended):
|
|
||||||
- `68.94.156.1`
|
|
||||||
- `68.94.157.1`
|
|
||||||
(These may be different depending on your location.)
|
|
||||||
6. Hit **Save**
|
|
||||||
3. Configure the IGMP Proxy.
|
|
||||||
1. Navigate to _Services > IGMP Proxy_
|
|
||||||
2. Check **Enable IGMP**
|
|
||||||
3. Click **Add**
|
|
||||||
4. Select your WAN interface under **Interface**
|
|
||||||
5. Enter a meaningful description if you so choose. I used `U-verse IPTV`
|
|
||||||
6. Set **Type** to `Upstream interface`
|
|
||||||
7. For **Networks**, enter `0.0.0.1/1`
|
|
||||||
8. Hit **Save**
|
|
||||||
9. Click **Add**
|
|
||||||
10. Select your LAN interface under **Interface**
|
|
||||||
11. Enter a meaningful description if you so choose. I used `U-verse IPTV`
|
|
||||||
12. Set **Type** to `Downstream interface`
|
|
||||||
13. For **Networks**, enter the network address in CIDR notation of your LAN.
|
|
||||||
14. Hit **Save**
|
|
||||||
4. Configure the firewall.
|
|
||||||
1. Navigate to _Firewall > Rules_
|
|
||||||
2. Select the _Floating_ tab.
|
|
||||||
3. Create a rule as follows:
|
|
||||||
- **Action**: `Pass`
|
|
||||||
- **Quick**: `Checked`
|
|
||||||
- **Interface**: `WAN, LAN`
|
|
||||||
- **Protocol**: `Any`
|
|
||||||
- **Destination**: `Network` `224.0.0.0/8`
|
|
||||||
- **Description**: `Allow multicast to U-verse IPTV`
|
|
||||||
- **Allow IP options**: `Checked`
|
|
||||||
4. Create another rule as follows:
|
|
||||||
- **Action**: `Pass`
|
|
||||||
- **Quick**: `Checked`
|
|
||||||
- **Interface**: `WAN, LAN`
|
|
||||||
- **Protocol**: `Any`
|
|
||||||
- **Destination**: `Network 239.0.0.0/8`
|
|
||||||
- **Description**: `Allow multicast to U-verse IPTV`
|
|
||||||
- **Allow IP options**: `Checked`
|
|
||||||
5. Save and apply your new rules.
|
|
||||||
|
|
||||||
If you made it this far your new setup should be complete!
|
|
||||||
|
|
||||||
## Troubleshooting
|
|
||||||
|
|
||||||
### My DVR isn't getting any channels!
|
|
||||||
|
|
||||||
Make sure that your DVR has a proper connection to the internet. Double-check your configuration and make sure that the DVR is allowed to receive traffic.
|
|
||||||
|
|
||||||
### I can select a channel and watch it, but after about 10 seconds the TV goes black or the video freezes!
|
|
||||||
|
|
||||||
This means your DVR isn't able to receive the multicast video stream. Recall that the first 10 seconds of watching a new channel are done via unicast while the DVR simultaneously requests IGMP membership, and then after about 10 seconds you should start seeing multicast traffic passing through your firewall. If you don't see multicast traffic at all, make sure that your IGMP proxy is setup correctly. It's possible that the server sending the video stream is not receiving your DVR's IGMP membership request. If you *do* see the multicast traffic, double-check your firewall rules and make sure that multicast traffic is allowed to pass and that it can reach the DVR.
|
|
||||||
|
|
||||||
## Afterthoughts
|
|
||||||
|
|
||||||
For the purposes of this guide, when configuring the upstream networks for the IGMP proxy, we entered `0.0.0.1/1`, when in fact this is just a catch-all for a majority of the IPv4 address space. While I was still doing my initial research on the proper setup for this, I could not find a definitive list of source IP addresses that AT&T's U-verse TV streams seem to come from, and other sources claimed there were just too many. The proper configuration for this would be to enter each of those networks/addresses, but I simply could not get an accurate list of them. If you're reading this and you would like to share your findings, please consider submitting an issue or pull request to edit this documentation.
|
|
||||||
|
|
||||||
If you did not isolate your DVR on its own network in your setup, you may need to configure additional network devices on your LAN if you have any. Since multicast traffic is now propogating throughout your LAN, if you are able to, you should do what is possible to limit the areas of your network where this traffic is allowed to propogate, especially if it is not needed except towards the DVR. This is especially true for wireless networks. Unfortunately, the exact procedures for doing this for each network device vary from vendor to vendor and are far beyond the scope of this guide, but the end goal is to simply disallow multicast traffic from passing through devices and into areas of the network where it is not needed.
|
|
|
@ -1,92 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
ONT_IF='em0'
|
|
||||||
RG_IF='em1'
|
|
||||||
RG_ETHER_ADDR='xx:xx:xx:xx:xx:xx'
|
|
||||||
LOG=/var/log/pfatt.log
|
|
||||||
|
|
||||||
getTimestamp(){
|
|
||||||
echo `date "+%Y-%m-%d %H:%M:%S :: [pfatt.sh] ::"`
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
echo "$(getTimestamp) pfSense + AT&T U-verse Residential Gateway for true bridge mode"
|
|
||||||
echo "$(getTimestamp) Configuration: "
|
|
||||||
echo "$(getTimestamp) ONT_IF: $ONT_IF"
|
|
||||||
echo "$(getTimestamp) RG_IF: $RG_IF"
|
|
||||||
echo "$(getTimestamp) RG_ETHER_ADDR: $RG_ETHER_ADDR"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) loading netgraph kernel modules... "
|
|
||||||
/sbin/kldload -nq netgraph
|
|
||||||
/sbin/kldload -nq ng_ether
|
|
||||||
/sbin/kldload -nq ng_etf
|
|
||||||
/sbin/kldload -nq ng_vlan
|
|
||||||
/sbin/kldload -nq ng_eiface
|
|
||||||
/sbin/kldload -nq ng_one2many
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo "$(getTimestamp) building netgraph nodes..."
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) creating ng_one2many... "
|
|
||||||
/usr/sbin/ngctl mkpeer $ONT_IF: one2many lower one
|
|
||||||
/usr/sbin/ngctl name $ONT_IF:lower o2m
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) creating vlan node and interface... "
|
|
||||||
/usr/sbin/ngctl mkpeer o2m: vlan many0 downstream
|
|
||||||
/usr/sbin/ngctl name o2m:many0 vlan0
|
|
||||||
/usr/sbin/ngctl mkpeer vlan0: eiface vlan0 ether
|
|
||||||
|
|
||||||
/usr/sbin/ngctl msg vlan0: 'addfilter { vlan=0 hook="vlan0" }'
|
|
||||||
/usr/sbin/ngctl msg ngeth0: set $RG_ETHER_ADDR
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) defining etf for $ONT_IF (ONT)... "
|
|
||||||
/usr/sbin/ngctl mkpeer o2m: etf many1 downstream
|
|
||||||
/usr/sbin/ngctl name o2m:many1 waneapfilter
|
|
||||||
/usr/sbin/ngctl connect waneapfilter: $ONT_IF: nomatch upper
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) defining etf for $RG_IF (RG)... "
|
|
||||||
/usr/sbin/ngctl mkpeer $RG_IF: etf lower downstream
|
|
||||||
/usr/sbin/ngctl name $RG_IF:lower laneapfilter
|
|
||||||
/usr/sbin/ngctl connect laneapfilter: $RG_IF: nomatch upper
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) bridging etf for $ONT_IF <-> $RG_IF... "
|
|
||||||
/usr/sbin/ngctl connect waneapfilter: laneapfilter: eapout eapout
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) defining filters for EAP traffic... "
|
|
||||||
/usr/sbin/ngctl msg waneapfilter: 'setfilter { matchhook="eapout" ethertype=0x888e }'
|
|
||||||
/usr/sbin/ngctl msg laneapfilter: 'setfilter { matchhook="eapout" ethertype=0x888e }'
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling one2many links... "
|
|
||||||
/usr/sbin/ngctl msg o2m: setconfig "{ xmitAlg=2 failAlg=1 enabledLinks=[ 1 1 ] }"
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) removing waneapfilter:nomatch hook... "
|
|
||||||
/usr/sbin/ngctl rmhook waneapfilter: nomatch
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling $RG_IF interface... "
|
|
||||||
/sbin/ifconfig $RG_IF up
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling $ONT_IF interface... "
|
|
||||||
/sbin/ifconfig $ONT_IF up
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling promiscuous mode on $RG_IF... "
|
|
||||||
/sbin/ifconfig $RG_IF promisc
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling promiscuous mode on $ONT_IF... "
|
|
||||||
/sbin/ifconfig $ONT_IF promisc
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo "$(getTimestamp) ngeth0 should now be available to configure as your pfSense WAN"
|
|
||||||
echo "$(getTimestamp) done!"
|
|
||||||
} >> $LOG
|
|
|
@ -1,50 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
|
|
||||||
script_path="/root/bin/pfatt-5268AC.sh"
|
|
||||||
|
|
||||||
name=`/usr/bin/basename "${script_path}"`
|
|
||||||
|
|
||||||
rc_start() {
|
|
||||||
### Lock out other start signals until we are done
|
|
||||||
/usr/bin/touch /var/run/${name}.lck
|
|
||||||
|
|
||||||
${script_path} &
|
|
||||||
pid=$!
|
|
||||||
|
|
||||||
if [ $pid ]; then
|
|
||||||
echo $pid > /var/run/${name}.pid
|
|
||||||
/usr/bin/logger -p daemon.info -i -t pfattStartup "Successfully started ${name}"
|
|
||||||
else
|
|
||||||
/usr/bin/logger -p daemon.error -i -t pfattStartup "Error starting ${name}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
### Remove the lock
|
|
||||||
if [ -f /var/run/${name}.lck ]; then
|
|
||||||
/bin/sleep 2
|
|
||||||
/bin/rm /var/run/${name}.lck
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
rc_stop() {
|
|
||||||
if [ -f /var/run/${name}.pid ]; then
|
|
||||||
kill -9 `cat /var/run/${name}.pid`
|
|
||||||
/bin/rm /var/run/${name}.pid
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
case $1 in
|
|
||||||
start)
|
|
||||||
if [ ! -f /var/run/${name}.lck ]; then
|
|
||||||
rc_start
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
stop)
|
|
||||||
rc_stop
|
|
||||||
;;
|
|
||||||
restart)
|
|
||||||
if [ ! -f /var/run/${name}.lck ]; then
|
|
||||||
rc_stop
|
|
||||||
rc_start
|
|
||||||
fi
|
|
||||||
;;
|
|
||||||
esac
|
|
|
@ -1,31 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
PING_HOST=8.8.8.8
|
|
||||||
SLEEP=5
|
|
||||||
LOG=/var/log/pfatt.log
|
|
||||||
|
|
||||||
getTimestamp(){
|
|
||||||
echo `date "+%Y-%m-%d %H:%M:%S :: [pfatt-5268AC.sh] ::"`
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
RG_CONNECTED="/usr/sbin/ngctl show laneapfilter:eapout"
|
|
||||||
|
|
||||||
echo "$(getTimestamp) Starting 5268AC ping monitor ..."
|
|
||||||
while
|
|
||||||
if /sbin/ping -t2 -q -c1 $PING_HOST > /dev/null ; then
|
|
||||||
if $RG_CONNECTED >/dev/null 2>&1 ; then
|
|
||||||
echo "$(getTimestamp) Connection to $PING_HOST is up, but EAP is being bridged!"
|
|
||||||
echo -n "$(getTimestamp) Disconnecting netgraph node ... "
|
|
||||||
/usr/sbin/ngctl rmhook laneapfilter: eapout && echo "OK!" || echo "ERROR!"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if ! $RG_CONNECTED >/dev/null 2>&1 ; then
|
|
||||||
echo "$(getTimestamp) Connection to $PING_HOST is down, but EAP is not being bridged!"
|
|
||||||
echo -n "$(getTimestamp) Connecting netgraph node ... "
|
|
||||||
/usr/sbin/ngctl connect waneapfilter: laneapfilter: eapout eapout && echo "OK!" || echo "ERROR!"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
sleep $SLEEP
|
|
||||||
do :; done
|
|
||||||
echo "$(getTimestamp) Stopping 5268AC ping monitor ..."
|
|
||||||
} >> $LOG
|
|
154
bin/pfatt.sh
154
bin/pfatt.sh
|
@ -1,9 +1,12 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
ONT_IF='xx0'
|
ONT_IF='xxx0'
|
||||||
RG_IF='xx1'
|
|
||||||
RG_ETHER_ADDR='xx:xx:xx:xx:xx:xx'
|
RG_ETHER_ADDR='xx:xx:xx:xx:xx:xx'
|
||||||
|
CA_PEM='xxx.pem'
|
||||||
|
CLIENT_PEM='xxx.pem'
|
||||||
|
PRIVATE_PEM='xxx.pem'
|
||||||
|
|
||||||
LOG=/var/log/pfatt.log
|
LOG=/var/log/pfatt.log
|
||||||
|
|
||||||
getTimestamp(){
|
getTimestamp(){
|
||||||
|
@ -11,78 +14,117 @@ getTimestamp(){
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
echo "$(getTimestamp) pfSense + AT&T U-verse Residential Gateway for true bridge mode"
|
echo "$(getTimestamp) pfSense + AT&T U-verse Residential Gateway bypass mode"
|
||||||
echo "$(getTimestamp) Configuration: "
|
echo "$(getTimestamp) Configuration: "
|
||||||
echo "$(getTimestamp) ONT_IF: $ONT_IF"
|
echo "$(getTimestamp) ONT_IF: $ONT_IF"
|
||||||
echo "$(getTimestamp) RG_IF: $RG_IF"
|
|
||||||
echo "$(getTimestamp) RG_ETHER_ADDR: $RG_ETHER_ADDR"
|
echo "$(getTimestamp) RG_ETHER_ADDR: $RG_ETHER_ADDR"
|
||||||
|
|
||||||
echo -n "$(getTimestamp) attaching interfaces to ng_ether... "
|
echo -n "$(getTimestamp) attaching interfaces to ng_ether... "
|
||||||
/usr/local/bin/php -r "pfSense_ngctl_attach('.', '$ONT_IF');"
|
/usr/local/bin/php -r "pfSense_ngctl_attach('.', '$ONT_IF');"
|
||||||
/usr/local/bin/php -r "pfSense_ngctl_attach('.', '$RG_IF');"
|
|
||||||
echo "OK!"
|
echo "OK!"
|
||||||
|
|
||||||
echo "$(getTimestamp) building netgraph nodes..."
|
echo "$(getTimestamp) building netgraph nodes..."
|
||||||
|
|
||||||
echo -n "$(getTimestamp) creating ng_one2many... "
|
|
||||||
/usr/sbin/ngctl mkpeer $ONT_IF: one2many lower one
|
|
||||||
/usr/sbin/ngctl name $ONT_IF:lower o2m
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) creating vlan node and interface... "
|
echo -n "$(getTimestamp) creating vlan node and interface... "
|
||||||
/usr/sbin/ngctl mkpeer o2m: vlan many0 downstream
|
/usr/sbin/ngctl mkpeer $ONT_IF: vlan lower downstream
|
||||||
/usr/sbin/ngctl name o2m:many0 vlan0
|
/usr/sbin/ngctl name $ONT_IF:lower vlan0
|
||||||
/usr/sbin/ngctl mkpeer vlan0: eiface vlan0 ether
|
/usr/sbin/ngctl mkpeer vlan0: eiface vlan0 ether
|
||||||
|
|
||||||
/usr/sbin/ngctl msg vlan0: 'addfilter { vlan=0 hook="vlan0" }'
|
/usr/sbin/ngctl msg vlan0: 'addfilter { vlan=0 hook="vlan0" }'
|
||||||
/usr/sbin/ngctl msg ngeth0: set $RG_ETHER_ADDR
|
/usr/sbin/ngctl msg ngeth0: set $RG_ETHER_ADDR
|
||||||
echo "OK!"
|
echo "OK!"
|
||||||
|
|
||||||
echo -n "$(getTimestamp) defining etf for $ONT_IF (ONT)... "
|
|
||||||
/usr/sbin/ngctl mkpeer o2m: etf many1 downstream
|
|
||||||
/usr/sbin/ngctl name o2m:many1 waneapfilter
|
|
||||||
/usr/sbin/ngctl connect waneapfilter: $ONT_IF: nomatch upper
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) defining etf for $RG_IF (RG)... "
|
|
||||||
/usr/sbin/ngctl mkpeer $RG_IF: etf lower downstream
|
|
||||||
/usr/sbin/ngctl name $RG_IF:lower laneapfilter
|
|
||||||
/usr/sbin/ngctl connect laneapfilter: $RG_IF: nomatch upper
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) bridging etf for $ONT_IF <-> $RG_IF... "
|
|
||||||
/usr/sbin/ngctl connect waneapfilter: laneapfilter: eapout eapout
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) defining filters for EAP traffic... "
|
|
||||||
/usr/sbin/ngctl msg waneapfilter: 'setfilter { matchhook="eapout" ethertype=0x888e }'
|
|
||||||
/usr/sbin/ngctl msg laneapfilter: 'setfilter { matchhook="eapout" ethertype=0x888e }'
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling one2many links... "
|
|
||||||
/usr/sbin/ngctl msg o2m: setconfig "{ xmitAlg=2 failAlg=1 enabledLinks=[ 1 1 ] }"
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) removing waneapfilter:nomatch hook... "
|
|
||||||
/usr/sbin/ngctl rmhook waneapfilter: nomatch
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling $RG_IF interface... "
|
|
||||||
/sbin/ifconfig $RG_IF up
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling $ONT_IF interface... "
|
echo -n "$(getTimestamp) enabling $ONT_IF interface... "
|
||||||
/sbin/ifconfig $ONT_IF up
|
/sbin/ifconfig $ONT_IF up
|
||||||
echo "OK!"
|
echo "OK!"
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling promiscuous mode on $RG_IF... "
|
|
||||||
/sbin/ifconfig $RG_IF promisc
|
|
||||||
echo "OK!"
|
|
||||||
|
|
||||||
echo -n "$(getTimestamp) enabling promiscuous mode on $ONT_IF... "
|
echo -n "$(getTimestamp) enabling promiscuous mode on $ONT_IF... "
|
||||||
/sbin/ifconfig $ONT_IF promisc
|
/sbin/ifconfig $ONT_IF promisc
|
||||||
echo "OK!"
|
echo "OK!"
|
||||||
|
|
||||||
|
# Enable this if Need to map physical port to RG MAC address:
|
||||||
|
# echo -n "$(getTimestamp) mapping physical port to RG MAC address... "
|
||||||
|
# /sbin/ifconfig $ONT_IF ether $RG_ETHER_ADDR
|
||||||
|
# echo "OK!"
|
||||||
|
|
||||||
|
## Added code
|
||||||
|
|
||||||
|
echo "$(getTimestamp) starting wpa_supplicant..."
|
||||||
|
|
||||||
|
WPA_PARAMS="\
|
||||||
|
set eapol_version 1,\
|
||||||
|
set fast_reauth 1,\
|
||||||
|
ap_scan 0,\
|
||||||
|
add_network,\
|
||||||
|
set_network 0 ca_cert \\\"/conf/pfatt/wpa/$CA_PEM\\\",\
|
||||||
|
set_network 0 client_cert \\\"/conf/pfatt/wpa/$CLIENT_PEM\\\",\
|
||||||
|
set_network 0 eap TLS,\
|
||||||
|
set_network 0 eapol_flags 0,\
|
||||||
|
set_network 0 identity \\\"$RG_ETHER_ADDR\\\",\
|
||||||
|
set_network 0 key_mgmt IEEE8021X,\
|
||||||
|
set_network 0 phase1 \\\"allow_canned_success=1\\\",\
|
||||||
|
set_network 0 private_key \\\"/conf/pfatt/wpa/$PRIVATE_PEM\\\",\
|
||||||
|
enable_network 0\
|
||||||
|
"
|
||||||
|
|
||||||
|
WPA_DAEMON_CMD="/usr/sbin/wpa_supplicant -Dwired -ingeth0 -B -C /var/run/wpa_supplicant"
|
||||||
|
# if the above doesn't work try: WPA_DAEMON_CMD="/usr/sbin/wpa_supplicant -Dwired -i$ONT_IF -B -C /var/run/wpa_supplicant"
|
||||||
|
|
||||||
|
# kill any existing wpa_supplicant process
|
||||||
|
echo -n "$(getTimestamp) killing any existing wpa_supplicant process... "
|
||||||
|
PID=$(pgrep -f "wpa_supplicant.*ngeth0")
|
||||||
|
if [ ${PID} > 0 ];
|
||||||
|
then
|
||||||
|
echo "$(getTimestamp) pfatt terminating existing wpa_supplicant on PID ${PID}..."
|
||||||
|
RES=$(kill ${PID})
|
||||||
|
fi
|
||||||
|
echo "OK!"
|
||||||
|
|
||||||
|
# start wpa_supplicant daemon
|
||||||
|
echo -n "$(getTimestamp) starting wpa_supplicant daemon... "
|
||||||
|
RES=$(${WPA_DAEMON_CMD})
|
||||||
|
PID=$(pgrep -f "wpa_supplicant.*ngeth0")
|
||||||
|
echo "$(getTimestamp) pfatt wpa_supplicant running on PID ${PID}..."
|
||||||
|
|
||||||
|
# Set WPA configuration parameters.
|
||||||
|
echo -n "$(getTimestamp) pfatt setting wpa_supplicant network configuration..."
|
||||||
|
IFS=","
|
||||||
|
for STR in ${WPA_PARAMS};
|
||||||
|
do
|
||||||
|
STR="$(echo -e "${STR}" | sed -e 's/^[[:space:]]*//')"
|
||||||
|
RES=$(eval wpa_cli ${STR})
|
||||||
|
done
|
||||||
|
echo "OK!"
|
||||||
|
|
||||||
|
# wait until wpa_cli has authenticated.
|
||||||
|
echo -n "$(getTimestamp) waiting until wpa_cli has authenticated..."
|
||||||
|
WPA_STATUS_CMD="wpa_cli status | grep 'suppPortStatus' | cut -d= -f2"
|
||||||
|
IP_STATUS_CMD="ifconfig ngeth0 | grep 'inet\ ' | cut -d' ' -f2"
|
||||||
|
echo "OK!"
|
||||||
|
|
||||||
|
# Get authorization
|
||||||
|
echo "$(getTimestamp) pfatt waiting EAP for authorization..."
|
||||||
|
while true;
|
||||||
|
do
|
||||||
|
WPA_STATUS=$(eval ${WPA_STATUS_CMD})
|
||||||
|
if [ X${WPA_STATUS} = X"Authorized" ];
|
||||||
|
then
|
||||||
|
echo "$(getTimestamp) pfatt EAP authorization completed..."
|
||||||
|
|
||||||
|
IP_STATUS=$(eval ${IP_STATUS_CMD})
|
||||||
|
|
||||||
|
if [ -z ${IP_STATUS} ] || [ ${IP_STATUS} = "0.0.0.0" ];
|
||||||
|
then
|
||||||
|
echo "$(getTimestamp) pfatt no IP address assigned, force restarting DHCP..."
|
||||||
|
RES=$(eval /etc/rc.d/dhclient forcerestart ngeth0)
|
||||||
|
IP_STATUS=$(eval ${IP_STATUS_CMD})
|
||||||
|
fi
|
||||||
|
echo "$(getTimestamp) pfatt IP address is ${IP_STATUS}..."
|
||||||
|
break
|
||||||
|
else
|
||||||
|
sleep 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo "$(getTimestamp) All done... ngeth0 should now be available to configure as your pfSense WAN"
|
||||||
|
|
||||||
echo "$(getTimestamp) ngeth0 should now be available to configure as your pfSense WAN"
|
|
||||||
echo "$(getTimestamp) done!"
|
|
||||||
} >> $LOG
|
} >> $LOG
|
||||||
|
|
BIN
img/netgraph.png
Normal file
BIN
img/netgraph.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
Loading…
Reference in a new issue