You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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.
20
23
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.
23
25
24
-
```bash
25
-
#!/bin/bash
26
-
set -e
27
-
28
-
# set AWS credentials to access S3 bucket which hosts the debian repository
-**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.
47
35
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).
> :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.
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.
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.
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.
0 commit comments