Skip to content

Commit 4129b1f

Browse files
authored
chore: release v0.0.4 (#5)
1 parent ac8d58c commit 4129b1f

File tree

11 files changed

+292
-58
lines changed

11 files changed

+292
-58
lines changed

.github/imgs/openkeychain.png

5.28 KB
Loading

.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
"request": "launch",
1111
"program": "${workspaceFolder}/src/build/tools/usb-mitm",
1212
"args": [
13-
// "-v", "045e", "-p", "07f8", "-n"
13+
// "-v", "045e", "-p", "07f8", "-n", "-l"
1414
"-v", "04e8", "-p", "3461", "-n", "-l"
1515
],
1616
"stopAtEntry": false,

README.md

Lines changed: 203 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -6,65 +6,228 @@ USB Proxy for Raspberry Pi (armhf)
66
</p>
77

88
![.github/workflows/build-app-nightly.yaml](https://github.com/nesto-software/USBProxy/workflows/.github/workflows/build-app-nightly.yaml/badge.svg?branch=dev)
9+
![.github/workflows/build-app-release.yaml](https://github.com/nesto-software/USBProxy/workflows/.github/workflows/build-app-release.yaml/badge.svg)
910

1011

11-
Status
12+
Heads Up!
1213
------
1314
This project is currently being refactored by Nesto.
1415
If you want to participate, feel free to reach out!
15-
16+
1617
Martin Löper `<[email protected]>`
1718

18-
Install
19+
Mission
1920
-------
21+
Nesto is developing an [IoT solution to interface Point of Sale (POS) systems](https://nesto-software.de/datenintegration/) for the German gastronomy. One strategy of integrating legacy systems on the market, is to observe the traffic between terminal and its printer. Printers are either connected via Ethernet or USB. We strive for a reliable software solution for mirroring print jobs using a Raspberry Pi as a USB proxy device.
22+
That is, the POS system is connected to the Raspberry Pi which in turn is connected to the printer. The Raspberry Pi is running additional software to export the obtained data securely into the cloud.
2023

21-
In order to install USBProxy on your Raspberry Pi, please use the following snippet.
22-
You must add AWS credentials at the top of the file in advance.
24+
We want to share our progress on this project with the open-source community as we [forked the original codebase](https://github.com/usb-tools/USBProxy-legacy) which is under the GPL-2.0.
2325

24-
```bash
25-
#!/bin/bash
26-
set -e
27-
28-
# set AWS credentials to access S3 bucket which hosts the debian repository
29-
ACCESS_KEY_ID=
30-
SECRET_ACCESS_KEY=
31-
32-
REGION=eu-central-1
33-
BUCKET=nesto-debian-repo-devel
34-
GPG_KEY_ID=92F91ABA4816493E
35-
PKG_NAME=nesto-usbproxy
36-
DISTRIBUTION=main # main or nightly
37-
38-
sudo apt-get update
39-
sudo apt-get install apt-transport-s3
40-
echo -e "AccessKeyId = '$ACCESS_KEY_ID'\nSecretAccessKey = '$SECRET_ACCESS_KEY'\nRegion = '$REGION'\nToken = ''" > /etc/apt/s3auth.conf
41-
echo "deb s3://$BUCKET $DISTRIBUTION aws" >> /etc/apt/sources.list
42-
gpg --keyserver keys.openpgp.org --receive-key "$GPG_KEY_ID"
43-
gpg --export --armor "$GPG_KEY_ID" | apt-key add -
44-
sudo apt-get update
45-
sudo apt-get install $PKG_NAME
46-
```
26+
Scope
27+
-------
28+
- **Tested Device**: [Raspberry Pi 4B](https://www.raspberrypi.org/products/raspberry-pi-4-model-b/specifications/)
29+
- **OS:** Linux
30+
- **Distribution**: Raspberry Pi OS / Raspbian (we use Debian's packaging system)
31+
- **Architecture**: armhf (we do not build for arm64 yet)
32+
- **Build System**: crosstool-NG (we are cross-compiling using GitHub workflows)
33+
- **Additional Plugins**: We implemented IPC capability using [ZeroMQ](http://zeromq.org/) to channel the data out to other applications (running Python or Node.js). The language bindings which were provided by the original project did not work for us (throwing segfaults).
34+
- **Additional Packaging**: We provide an alternative version of the application as [AWS Greengrass Lambda Package](https://github.com/aws/aws-greengrass-core-sdk-c). [Greengrass](https://aws.amazon.com/de/greengrass/) can be used to run the application on IoT devices in production. It guarantees that the process is running isolated and does stuff similar to systemd, such as auto-restarting the application on failure. Furthermore, it is an integral part of delivering a secure transport into the AWS cloud.
4735

48-
```bash
49-
#!/bin/bash
50-
set -e
36+
> :information_source: **Supported Devices**: There are many more devices which are working with this application. You have to make sure the device has a USB port which can operate in client mode. OTG ports are usually capable of doing that. Make also sure your device is being added to the [list of device ids for GadgetFS](https://github.com/nesto-software/USBProxy/blob/master/src/Plugins/Hosts/GadgetFS_helpers.c#L188).
5137
52-
FILE=/tmp/nesto-usbproxy-latest.deb
5338

54-
curl -s https://api.github.com/repos/nesto-software/USBProxy/releases/latest \
55-
| grep "browser_download_url.*deb" \
56-
| cut -d : -f 2,3 \
57-
| tr -d \" \
58-
| wget -qi - -O "$FILE"
39+
## Installation
5940

60-
sudo dpkg -i "$FILE"
61-
```
41+
There are 4 installation methods:
42+
- Binaries uploaded to GitHub releases (public; production ready)
43+
- Binaries uploaded to Debian repository on S3 (Nesto-internal; production & nightly builds)
44+
- Manually cross-compile source code (using code in *./docker-crosstool-ng-arm* folder)
45+
- Manually compile source code on the Raspberry Pi using [VS Code Remote Development](https://code.visualstudio.com/docs/remote/remote-overview)
46+
47+
We provide instructions for each method in the following.
48+
49+
### Install via GitHub Releases Download (binary)
6250

6351
| Method | Command |
6452
|:----------|:--------------------------------------------------------------------------------------------------|
6553
| **curl** | `sh -c "$(curl -fsSL https://raw.githubusercontent.com/nesto-software/USBProxy/master/scripts/install-from-release.sh)"` |
6654
| **wget** | `sh -c "$(wget -O- https://raw.githubusercontent.com/nesto-software/USBProxy/master/scripts/install-from-release.sh)"` |
6755

56+
### Install via APT Package Manager (binary)
57+
58+
> :information_source: **Internal**: We cannot provide a public package repository at the moment. The access is thus restricted to project members and Nesto employees. Others should use the GitHub releases option above.
59+
60+
61+
| Method | Command |
62+
|:----------|:--------------------------------------------------------------------------------------------------|
63+
| **curl** | `sh -c "$(curl -fsSL https://raw.githubusercontent.com/nesto-software/USBProxy/master/rpi-scripts/install-repo.sh)"` |
64+
| **wget** | `sh -c "$(wget -O- https://raw.githubusercontent.com/nesto-software/USBProxy/master/rpi-scripts/install-repo.sh)"` |
65+
66+
### Manually compile on x86-64 (source)
67+
```bash
68+
cd ./docker-crosstool-ng-arm
69+
./build-binary.sh
70+
```
71+
72+
The binary should be cross-compiled using a docker container and the result is placed in `docker-crosstool-ng-arm/bin`.
73+
74+
### Manually compile on armhf (source)
75+
This option is the fastest for development.
76+
77+
#### Prepare Raspberry Pi and Connection to Laptop
78+
79+
1. Install rpi-imager: `sudo apt install rpi-imager`
80+
2. Insert SD card into laptop
81+
3. Start rpi-imager, choose SD card, choose *Raspberry Pi OS (Other)* -> *Raspberry Pi OS Lite (32-bit)* and flash
82+
4. Mount the SD card on your laptop and set env variable $SD_BOOT to boot partition and $SD_DATA to data partition
83+
5. Enable ssh for the pi by placing an empty file called *ssh* into boot partition: `touch ${SD_BOOT}/ssh`
84+
6. Set a link-local IP for your pi by appending the following to *${SD_DATA}/etc/network/interfaces*:
85+
```
86+
auto eth0
87+
allow-hotplug eth0
88+
iface eth0 inet static
89+
address 169.254.100.1
90+
netmask 255.255.255.0
91+
gateway 169.254.100.2
92+
```
93+
7. Insert the SD card into your pi and connect the pi to your laptop using an ethernet cable
94+
8. Boot your pi. It should be accessible via the link-local ip `169.254.100.1`.
95+
9. Configure your laptop with a link-local ip (e.g. *169.254.100.2*) on the interface which is connected to the pi (e.g. a USB to ethernet adapter labeled *enx00e04c6b1c7b*):
96+
```
97+
sudo ip addr add 169.254.100.2 dev enx00e04c6b1c7b
98+
sudo route add -net 169.254.0.0 netmask 255.255.0.0 dev enx00e04c6b1c7b
99+
```
100+
10. Allow the pi to access the internet via your laptop by confguring your laptop accordingly as follows:
101+
```
102+
# enable ip forwarding
103+
sysctl -w net.ipv4.ip_forward=1
104+
105+
# enable ip masquerading on the interface which is used to access the internet (e.g. wlp59s0)
106+
sudo iptables -t nat -A POSTROUTING -o wlp59s0 -j MASQUERADE
107+
```
108+
11. Connect to the pi using ssh: `ssh [email protected]` using default password `raspberry`.
109+
12. Check if your pi can access the internet via your laptop: `ping 8.8.8.8` and `ping google.de` (to check domain resolution)
110+
111+
#### Preparing the development environment
112+
1. Install [Visual Studio Code](https://code.visualstudio.com/download)
113+
2. Install the following extensions: `ms-vscode-remote.remote-ssh` and `ms-vscode-remote.remote-ssh-edit`
114+
3. Restart VSCode
115+
4. Open the default configuration file using Ctrl+Shift+P + *Remote-SSH: Open Configuration File...* -> Choose default config file in your user's home directory (i.e. *~/.ssh/config*) and paste the following:
116+
```
117+
Host Pi
118+
HostName 169.254.100.1
119+
User pi
120+
```
121+
5. Connect to the Pi using Ctrl+Shift+P + *Remote-SSH: Connect to Host...* -> Pi and with the default password *raspberry* (when prompted for it). This might take a while because VSCode will transfer a bundle to the pi and install everything that is needed for remote development.
122+
6. Install remote VSCode extensions: `ms-vscode.cpptools`, `twxs.cmake`, `ms-vscode.cmake-tools`
123+
7. Open a new terminal on the remote device using Ctrl+Shift+` and use it for subsequent Linux commands
124+
8. Optional: Create a personal access token to be able to clone the USB Proxy repo and push to it. The token needs the *public_repo* scope.
125+
9. Clone the USB Proxy repository from GitHub: `git clone https://${TOKEN}:[email protected]/nesto-software/USBProxy.git`
126+
10. Open the folder inside the explorer using Ctrl+Shift+E -> */home/pi/USBProxy/*
127+
128+
#### Installing dependencies
129+
- Run `./rpi-scripts/install-all-dependencies.sh`
130+
131+
#### Compiling
132+
1. Click on the Build button in the bottom VSCode task bar
133+
2. Choose a kit (e.g. GCC 7.5.0)
134+
3. Wait for the build to finish
135+
136+
If the build finished without errors, you could try to install and run the binary.
137+
138+
139+
#### Install and run (with debugger attached)
140+
1. Connect a host device to the raspberry pi's USB C port. This could be another Linux computer or even the same device which you are using for remote development.
141+
2. Connect a client device to one of the raspberry pi's USB A ports. This could be a USB keyboard for example.
142+
3. Find out the keyboard's USB vendor and product ID:
143+
```bash
144+
sudo apt install usbutils
145+
sudo lsusb -v
146+
```
147+
4. The header of the device descriptor looks something like this: `Bus 001 Device 004: ID 045e:07f8 Microsoft Corp. Wired Keyboard 600 (model 1576)` with *045e* being the vendor id and *07f8* being the product id.
148+
5. Open `.vscode/launch.json` and adjust the *-v* and *-p* arguments in L14 with the values obtained from step 4. Example given in L13.
149+
6. Open the *Run and Debug* view using Ctlr+Shift+D and start the *Install + Run* launch configuration
150+
151+
Please note that you must run the application with root privileges. The launch configuration takes care of that for you.
152+
153+
If you want to run the script on your own, make sure to run the install task before (i.e. Ctrl+P -> *task install* -> Enter -> Enter). This is needed to copy shared libraries into appropriate system folders. You can run the binary from the repository root by doing: `./src/build/tools/usb-mitm --help`. Do not forget to use **sudo** when running anything other than the help menu view. We need root permissions to access the usb subsystem and read from devices.
154+
155+
Usage
156+
---------
157+
```
158+
usb-mitm - command line tool for controlling USBProxy
159+
Usage: ./src/build/tools/usb-mitm [OPTIONS]
160+
Options:
161+
-v <vendorId> VendorID of target device
162+
-p <productId> ProductID of target device
163+
-P <PluginName> Use PluginName (order is preserved)
164+
-D <DeviceProxy> Use DeviceProxy
165+
-H <HostProxy> Use HostProxy
166+
-d Enable debug messages (-dd for increased verbosity)
167+
-s Server mode, listen on port 10400
168+
-c <hostname | address> Client mode, connect to server at hostname or address
169+
-l Enable stream logger (logs to stderr)
170+
-i Enable UDP injector
171+
-x Enable Xbox360 UDPHID injector & filter
172+
-k Keylogger with ROT13 filter (for demo), specify optional filename to output to instead of stderr
173+
-w <filename> Write to pcap file for viewing in Wireshark
174+
-h Display this message
175+
```
176+
177+
There is a new option `-n` which registers the ZeroMQ filter.
178+
68179
GPG
69180
---------
70-
<a href="https://keyoxide.org/F1C6636C27019FD0D29307DEAE25CBF30C0DDB0C" rel="Nesto Cloud Operations">![Nesto Cloud Operations](.github/imgs/gpg_qr.svg)</a>
181+
182+
#### Add our key to your keychain!
183+
184+
We use [GPG](https://de.wikipedia.org/wiki/GNU_Privacy_Guard) to sign our binary releases.
185+
In order to install packages from internal repositories, you must add our key for SecureApt to work.
186+
The GitHub releases do not provide signatures - just download the respective .deb file and you are ready to go.
187+
188+
<a target="_blank" href="https://keyoxide.org/F1C6636C27019FD0D29307DEAE25CBF30C0DDB0C" rel="Nesto Cloud Operations">![Nesto Cloud Operations](.github/imgs/gpg_qr.svg)</a>
189+
190+
<img align="left" src=".github/imgs/openkeychain.png" width="50px">
191+
<a target="_blank" href="https://www.openkeychain.org/">Download OpenKeychain for Android</a><br />
192+
<a target="_blank" href="https://gnupg.org/download/">Download GNU Privacy Guard for Linux</a>
193+
<br clear="both">
194+
<br />
195+
<b>Keyserver: <a target="_blank" href="https://keys.openpgp.org/search?q=F1C6636C27019FD0D29307DEAE25CBF30C0DDB0C">keys.openpgp.org</a></b>
196+
197+
IPC Example
198+
---------
199+
We provided a sample application for Node.js in the *./nodejs-client* folder.
200+
The sample application connects to the USB Proxy and receives data which is read from the USB relaying.
201+
202+
You can run the example by doing:
203+
1. Start the usb-mitm application, e.g. using `./scripts/usb-mitm.sh` if you already built it. Please make sure to adjust the vendor and product ids in the shell script beforehand.
204+
2. Install Node.js binary from [nodejs.org](https://nodejs.org/en/download/) or via nvm.
205+
3. Install Node.js dependencies:
206+
```bash
207+
cd nodejs-client
208+
npm install
209+
```
210+
4. Run the script: `node ./nodejs-client/index.js`
211+
5. You should see that the application receives buffers once data is transferred between your USB device and the host. In case you are using a USB keyboard as test device, you should see an incoming buffer for each keydown and keyup event.
212+
213+
Development
214+
----------
215+
216+
We use the following Git Feature-Branch-Workflow:
217+
218+
The master branch is used to build stable releases. The code in master must always compile. Only project maintainers are allowed to merge into master via a PR. Merging into master is allowed from dev branch only. Merging into master usually results into a new release version when files inside the *src* folder are modified.
219+
220+
The dev branch is used to prepare a release. Developers are expected to merge or rebase their branch with dev frequently. The dev branch is used to build nightly releases. The code in dev should always compile. Merging into dev is allowed from all feature branches and requires a PR which must be approved by at least one project maintainer. Merging into dev results into an instant nightly release when files inside the *src* folder are modified.
221+
222+
Developers are expected to fork the repository and to work on their own feature branches. Once the work is done, please submit a PR into dev branch. We will merge into master and create a release as soon as possible.
223+
224+
Building a Release (for Maintainers)
225+
----------
226+
227+
1. Switch to dev branch and pull
228+
2. `./.github/create-release.sh (major|minor|patch)`
229+
3. git add -A && git commit && git push
230+
4. Create a PR into master and describe the changes; Make sure to squash the commits.
231+
232+
Use a commit message like: `chore: prepare release for vx.y.z`.
233+
Use a PR title like: `chore: release vx.y.z`.

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.3
1+
0.0.4
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#!/bin/bash
2+
set -e
3+
set -o pipefail
4+
5+
echo -e "[0/7] Updating package list\n"
6+
sudo apt-get update
7+
8+
echo -e "[1/7] Installing cmake"
9+
sudo apt-get install -y cmake
10+
11+
echo -e "[2/7] Installing libusb\n"
12+
sudo apt-get install -y libusb-1.0.0-dev
13+
14+
echo -e "[3/7] Installing boost libs: chrono, timer, system\n"
15+
sudo apt-get install -y libboost-chrono-dev libboost-timer-dev libboost-system-dev
16+
17+
echo -e "[4/7] Installing libzmq\n"
18+
sudo apt-get install -y libzmq3-dev
19+
20+
echo -e "[5/7] Installing cppzmq\n"
21+
git clone https://github.com/zeromq/cppzmq.git /tmp/cppzmq || echo "Skipped clone."
22+
(cd /tmp/cppzmq && mkdir -p build && cd build && cmake -DCPPZMQ_BUILD_TESTS=off .. && sudo make -j4 install)
23+
24+
echo -e "[6/7] Installing msgpack\n"
25+
git clone https://github.com/msgpack/msgpack-c.git /tmp/msgpack-c || echo "Skipped clone."
26+
(cd /tmp/msgpack-c && git checkout cpp_master && cmake -DMSGPACK_CXX17=ON . && sudo make install)
27+
28+
echo -e "[7/7] Put RPi USB into client mode"
29+
set +e
30+
set +o pipefail
31+
32+
cat /boot/config.txt | grep -q dwc2
33+
rc=$?
34+
35+
if [ $rc -ne 0 ]; then
36+
echo "dtoverlay=dwc2" | sudo tee -a /boot/config.txt
37+
echo "dwc2" | sudo tee -a /etc/modules
38+
39+
echo "Changed USB c port to OTG client mode."
40+
fi
41+
42+
echo -e "\nYou must restart the pi now for changes to usb mode to take effect!!! Use: 'sudo reboot now'\n"

rpi-scripts/install-repo.sh

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,41 @@
11
#!/bin/bash
2+
set -e
23

3-
if [ -z "$1" ]; then
4-
echo "Pass AccessKeyId as first parameter."
5-
exit 1
6-
fi
4+
echo "This script is intended to configure the debian repository for the USB Proxy project and install the latest binary."
5+
echo ""
6+
echo "Setting up the APT repository which is hosted on S3..."
77

8-
if [ -z "$2" ]; then
9-
echo "Pass SecretAccessKey as second parameter."
10-
exit 1
11-
fi
8+
read -p 'AWS Access Key: '
9+
echo "";
10+
ACCESS_KEY_ID=${REPLY}
1211

12+
read -s -p 'AWS Secret Access Key (hidden input): '
13+
echo "";
14+
SECRET_ACCESS_KEY=${REPLY}
15+
16+
REGION=eu-central-1
17+
BUCKET=nesto-debian-repo-devel
18+
GPG_KEY_ID=92F91ABA4816493E
19+
PKG_NAME=nesto-usbproxy
20+
GPG_KEYSERVER=keys.openpgp.org
21+
22+
echo "Installing tools which are needed by APT to access S3..."
1323
sudo apt-get update
1424
sudo apt-get install apt-transport-s3
15-
echo -e "AccessKeyId = '$1'\nSecretAccessKey = '$2'\nRegion = 'eu-central-1'\nToken = ''" > /etc/apt/s3auth.conf
16-
echo "deb s3://nesto-debian-repo-devel unofficial local" >> /etc/apt/sources.list
17-
gpg --keyserver keys.openpgp.org --receive-key 92F91ABA4816493E
18-
gpg --export --armor "92F91ABA4816493E" | apt-key add -
25+
26+
echo "Configuring the S3 transport for APT..."
27+
echo -e "AccessKeyId = '$ACCESS_KEY_ID'\nSecretAccessKey = '$SECRET_ACCESS_KEY'\nRegion = '$REGION'\nToken = ''" > /etc/apt/s3auth.conf
28+
29+
# note: please do not use nightly for production systems
30+
echo "deb s3://$BUCKET main aws" >> /etc/apt/sources.list
31+
echo "deb s3://$BUCKET nightly aws" >> /etc/apt/sources.list
32+
33+
echo "Setting up APT keys for our S3 repo..."
34+
gpg --keyserver "$GPG_KEYSERVER" --receive-key "$GPG_KEY_ID"
35+
gpg --export --armor "$GPG_KEY_ID" | apt-key add -
36+
37+
echo "Updating the package list with the index from our S3 repo..."
1938
sudo apt-get update
20-
sudo apt-get install nesto-usbproxy
39+
40+
echo "Finally installing the latest version of our application..."
41+
sudo apt-get install $PKG_NAME

scripts/install-from-release.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@ set -e
33

44
FILE=/tmp/nesto-usbproxy-latest.deb
55

6+
echo "Downloading .deb file from latest GitHub release..."
67
curl -s https://api.github.com/repos/nesto-software/USBProxy/releases/latest \
78
| grep "browser_download_url.*deb" \
89
| cut -d : -f 2,3 \
910
| tr -d \" \
1011
| wget -qi - -O "$FILE"
1112

13+
echo "Installing .deb file..."
1214
sudo dpkg -i "$FILE"

0 commit comments

Comments
 (0)