Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable networking + SSHd over USB composite #73

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

htruong
Copy link
Contributor

@htruong htruong commented Dec 12, 2020

Enable link-local networking and SSHd

When the sentinel enable-usb-network is placed on /boot, then enable
networking features. This enables a dropbear instance and the avahi
daemon to advertise the ssh daemon.

Original:

As the first stepping stone to provide rich experiences such as firmware
upgrade from host and more #54, we need to enable networking over USB
composite interface.

The RNDIS interface is chosen because it seems like it has the widest
support among operating systems, albeit a bit proprietary.

You can now SSH to the camera via IP address 192.168.68.1. Set the
computer's IP to 192.168.68.2/24. Use root/root as the credential.

@htruong
Copy link
Contributor Author

htruong commented Dec 12, 2020

Turning on sshd will probably make our lives debugging this thing easier too, since most everyone know how to ssh. We can also transfer files back and forth and thus can easily bind-mount stuff. This will allow faster development iteration.

package/piwebcam/multi-gadget.sh Outdated Show resolved Hide resolved
board/rootfs/usr/lib/systemd/system/sshd.service Outdated Show resolved Hide resolved
board/rootfs/usr/lib/systemd/system/sshd.service Outdated Show resolved Hide resolved
@tuyenld
Copy link
Contributor

tuyenld commented Dec 13, 2020

@htruong,

Using http server has several advantage:

  • it is easy to create all camera setting on HTML, then we can configure these setting from WebUI
  • it don't need to encrypt/decrypt file when upgrade firmware as ssh do.
  • we still can create a terminal on WebUI

@tuyenld
Copy link
Contributor

tuyenld commented Dec 13, 2020

stephenrwarren commented in here: https://www.reddit.com/r/JetsonNano/comments/dwno63/usb_driver_for_mac_os_catalina/

Specifically, the ECM driver no longer works if the ECM function is part of a USB composite device, but does work if the ECM function is the the only function in the USB device

So, neither RNDIS nor ECM work along with UVC.
Here is my idea:

  • check the existance of /boot/picam_config which contain information about OS
  • if yes, switch off UVC, switch on ECM/RNDIS depend on content of picam_config
  • user have chance to configure Picam via WebUI
  • picam_config will be deleted after that, Picam will function normally

@dgsiegel
Copy link
Contributor

You might also want to check out dropbear, which is a smaller SSH server than OpenSSH.

Also I don't think you need to set up IP addresses, Bonjour should be enough.

@htruong
Copy link
Contributor Author

htruong commented Dec 13, 2020

The reason I chose openssh is because we will need scp to copy files to and from the camera. Dropbear doesn't have a sftp server so we ended up having openssh anyway. Unless someone has an idea how to do scp with dropbear.

I will figure out what to do with rndis and webcam.

@rossiniscarface
Copy link

As far as i know you don't need a full sftp server for scp. Only a scp client.
e.g. OpenWRT a lightweight router distro only links /usr/bin/scp to /usr/sbin/dropbear and this is all it takes to scp files to and from the router.

@rossiniscarface
Copy link

here another description https://www.emcraft.com/som/secure-copy

@htruong
Copy link
Contributor Author

htruong commented Dec 20, 2020

e.g. OpenWRT a lightweight router distro only links /usr/bin/scp to /usr/sbin/dropbear and this is all it takes to scp files to and from the router.

That's really wild. I really didn't know that!

@dgsiegel
Copy link
Contributor

I really really don't want any static IP inside the Raspberry. This is a promise that things will break (think about VPNs, company networks and so on). Have a look at Bonjour which might help to create a link-local raspberry.local device.

@htruong
Copy link
Contributor Author

htruong commented Dec 22, 2020

I have incorporated everyone's suggestions and we have a much cleaner PR now.

  • We have dropbear instead of OpenSSH so less drama.
  • We have avahi now:
+ enxcaffb7256799 IPv6 piwebcam                                      SSH Remote Terminal  local
+ enxcaffb7256799 IPv6 piwebcam                                      SFTP File Transfer   local
+ enxcaffb7256799 IPv4 piwebcam                                      SSH Remote Terminal  local
+ enxcaffb7256799 IPv4 piwebcam                                      SFTP File Transfer   local
  • You can ssh root@piwebcam when the /boot/enable-usb-network file is present.

@tuyenld
Copy link
Contributor

tuyenld commented Dec 22, 2020

I have confused.
For example, the content of /boot/usb-gadget.txt

CONFIGURE_USB_SERIAL=false
CONFIGURE_USB_WEBCAM=true
CONFIGURE_USB_NETWORK=false

If /boot/enable-usb-network is present, regardless content of /boot/usb-gadget.txt usb-network will be enable.
If /boot/disable-webcam is present, regardless content of /boot/usb-gadget.txt Webcam will be disable.
Why don't you only put on/off these function in one place (i.e. /boot/usb-gadget.txt)? It is more understandable.

@htruong
Copy link
Contributor Author

htruong commented Dec 22, 2020

@tuyenld I have abandoned the idea of using the usb-gadget.txt. Instead we have the three separate sentinels that you can use to turn on and off the usb features. If there is nothing in boot then the only thing that will show up is the uvc webcam.

@tuyenld
Copy link
Contributor

tuyenld commented Dec 22, 2020

@tuyenld I have abandoned the idea of using the usb-gadget.txt. Instead we have the three separate sentinels that you can use to turn on and off the usb features. If there is nothing in boot then the only thing that will show up is the uvc webcam.

Why don't you remove usb-gadget.txt?

@tuyenld
Copy link
Contributor

tuyenld commented Dec 22, 2020

I have a problem using avahi on Debian.
My PC recognizes piwebcam, but I can't connect:

ldtuyen@pc:~$ avahi-discover
Browsing domain 'local' on -1.-1 ...
Browsing domain 'lan' on -1.-1 ...
Browsing for services of type '_sftp-ssh._tcp' in domain 'local' on 3.1 ...
Browsing for services of type '_ssh._tcp' in domain 'local' on 3.1 ...
Found service 'piwebcam' of type '_sftp-ssh._tcp' in domain 'local' on 3.1.
Found service 'piwebcam' of type '_ssh._tcp' in domain 'local' on 3.1.

ldtuyen@pc:~$ ssh root@piwebcam
ssh: Could not resolve hostname piwebcam: Name or service not known
ldtuyen@pc:~$ 
ldtuyen@pc:~$ ssh root@piwebcam.local
ssh: Could not resolve hostname piwebcam.local: Name or service not known
ldtuyen@pc:~$ 
ldtuyen@pc:~$ 
ldtuyen@pc:~$ ssh root@piwebcam.local
ssh: Could not resolve hostname piwebcam.local: Name or service not known
ldtuyen@pc:~$ 
ldtuyen@pc:~$ 
ldtuyen@pc:~$ 
ldtuyen@pc:~$ ping piwebcam
ping: piwebcam: Name or service not known
ldtuyen@pc:~$ ping piwebcam.local
ping: piwebcam.local: Name or service not known
ldtuyen@pc:~$ 

Did I miss something?

@htruong
Copy link
Contributor Author

htruong commented Dec 22, 2020

Why don't you remove usb-gadget.txt?

Must have been an oopsie. Sorry, late night code...

For the ip, you have to configure the ipv4 of the connection from the pi to be link-local, it looks like Linux doesn't fall back to link-local addresses when dhcp fails. Then avahi-browse will tell you that you have a piwebcam on ipv4. Then the hostname to use is piwebcam.local.

Edit: Found the oopsie and fixed the dangling config. I didn't rebase correctly.

@htruong htruong force-pushed the user/htruong/rndis branch 2 times, most recently from 3b1c3f4 to 6c5950c Compare December 24, 2020 02:23
@tuyenld
Copy link
Contributor

tuyenld commented Dec 26, 2020

@htruong,
Take your time, we don't need to be rush _^_

Here is the result on my Debian PC.

To make network-gadget work on Debian, I have to configure a network interface to Link-Local:

image

Every time, I reboot Pi with network-gadget enabled, I got this warning:

ldtuyen@pc:~$ scp .dmrc root@piwebcam.local:/tmp/dmrc
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@       WARNING: POSSIBLE DNS SPOOFING DETECTED!          @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
The ECDSA host key for piwebcam.local has changed,
and the key for the corresponding IP address 169.254.13.107
has a different value. This could either mean that
DNS SPOOFING is happening or the IP address for the host
and its host key have changed at the same time.
Offending key for IP in /home/ldtuyen/.ssh/known_hosts:22
  remove with:
  ssh-keygen -f "/home/ldtuyen/.ssh/known_hosts" -R "169.254.13.107"
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
SHA256:nRYggjRkMoau4amAdMOdeElA6SHFZVF9xbzZPpGCbXA.
Please contact your system administrator.
Add correct host key in /home/ldtuyen/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/ldtuyen/.ssh/known_hosts:23
  remove with:
  ssh-keygen -f "/home/ldtuyen/.ssh/known_hosts" -R "piwebcam.local"
ECDSA host key for piwebcam.local has changed and you have requested strict checking.
Host key verification failed.
lost connection

I have to remove the old ssh key

ssh-keygen -f "/home/ldtuyen/.ssh/known_hosts" -R "169.254.13.107"
ssh-keygen -f "/home/ldtuyen/.ssh/known_hosts" -R "piwebcam.local"

Test cases and result:

Test case \ sentinels enable-usb-network disable-webcam enable-serial-debug Result
Default no no no Only uvc work
1 yes no no - uvc OK
- network OK (tested by using scp
- serial: disabled
2 yes no yes - uvc OK
- network OK (tested by using scp
- serial: OK
3 yes yes yes - uvc: disabled
- network: OK (tested by using scp
- serial: OK
4 no yes yes - uvc: disabled
- network: disabled
- serial: OK

It is all good on Linux.

@tuyenld
Copy link
Contributor

tuyenld commented Dec 27, 2020

I tested on Window 7

Window 7 failed to load RDINS driver.
The drivers for this device are not installed. (Code 28)

ảnh

# ls -la /boot/
total 8018
drwxr-xr-x    3 root     root         16384 Jan  1  1970 .
drwxr-xr-x   17 root     root           260 Dec 24  2020 ..
-rwxr-xr-x    1 root     root         24940 Dec 24  2020 bcm2708-rpi-zero.dtb
-rwxr-xr-x    1 root     root         52480 Dec 24  2020 bootcode.bin
-rwxr-xr-x    1 root     root           214 Dec 24  2020 camera.txt
-rwxr-xr-x    1 root     root           125 Dec 24  2020 cmdline.txt
-rwxr-xr-x    1 root     root           902 Dec 24  2020 config.txt
-rwxr-xr-x    1 root     root             0 Sep 12 12:19 disable-webcam
-rwxr-xr-x    1 root     root             6 Sep 12 12:18 enable-usb-network
-rwxr-xr-x    1 root     root         10278 Dec 24  2020 fixup.dat
drwxr-xr-x    2 root     root         18432 Dec 24  2020 overlays
-rwxr-xr-x    1 root     root       3708488 Dec 24  2020 start.elf
-rwxr-xr-x    1 root     root       4364744 Dec 24  2020 zImage
#

That is why I fake idVendor and idProduct in #76

@htruong
Copy link
Contributor Author

htruong commented Jan 3, 2021

If you configure the usb-gadget correctly, you can get the USB composite device show up on Windows fine without having to fake the PID and VID, and you don't have to disable webcam either.

I have just pushed a WIP here -- the device shows up in Linux, mac, and Windows as a composite device. The only problem left is that somehow I broke uvc-webcam and we can no longer use this as a webcam. But I think maybe I won half of the battle here.

@htruong
Copy link
Contributor Author

htruong commented Jan 3, 2021

Discussion over here:

https://gist.github.com/Gadgetoid/c52ee2e04f1cd1c0854c3e77360011e2

And the script over here:

https://github.com/RoganDawes/P4wnP1/blob/master/boot/init_usb.sh

Gave a lot of insights into how we can achieve composite USB on Windows.

@htruong
Copy link
Contributor Author

htruong commented Jan 4, 2021

It is apparent to me that for some reason, whatever the first device that gets configured (ln -s) first, then it will be the one that works correctly. Everything after that, except for the serial interface, doesn't work correctly.

Specifically -- If you initialize network -> webcam, then webcam doesn't work - regardless of OS.

If you initialize webcam -> network, then network doesn't work on Windows only, but it works on Linux.

Trying to figure out why.

- Enable networking features when a sentinel is placed in /boot.
- Enable avahi to provide a link-local IP address.
- Enable dropbear as the SSH and SFTP daemon.
@htruong
Copy link
Contributor Author

htruong commented Jan 4, 2021

Please hold on to testing and reviewing this PR. I think I got somewhere with the EEM driver, but there are something that I don't yet understand about this.

@tuyenld
Copy link
Contributor

tuyenld commented Jan 4, 2021

@htruong
I tested your latest commit (sdcard-raspberrypi0-d4dce7b.img), but RDNIS still fail in my Window 7.

# ls -la /boot/
total 8020
drwxr-xr-x    3 root     root         16384 Jan  1  1970 .
drwxr-xr-x   17 root     root           260 Jan  4  2021 ..
-rwxr-xr-x    1 root     root         24940 Jan  4  2021 bcm2708-rpi-zero.dtb
-rwxr-xr-x    1 root     root         52480 Jan  4  2021 bootcode.bin
-rwxr-xr-x    1 root     root           214 Jan  4  2021 camera.txt
-rwxr-xr-x    1 root     root           125 Jan  4  2021 cmdline.txt
-rwxr-xr-x    1 root     root           902 Jan  4  2021 config.txt
-rwxr-xr-x    1 root     root             0 Sep 12 12:19 disable-webcam
-rwxr-xr-x    1 root     root          1314 Jan  4  2021 enable-serial-debug
-rwxr-xr-x    1 root     root             6 Sep 12 12:19 enable-usb-network
-rwxr-xr-x    1 root     root         10278 Jan  4  2021 fixup.dat
drwxr-xr-x    2 root     root         18432 Jan  4  2021 overlays
-rwxr-xr-x    1 root     root       3708488 Jan  4  2021 start.elf
-rwxr-xr-x    1 root     root       4364744 Jan  4  2021 zImage
# cat /boot/enable-usb-network
RNDIS
#

ảnh

As you can see, window recognize USB composite device, but fail to find driver for RNDIS.
I know that I can fix this by point to other available RNDIS driver. But it isn't plug-and-play solution, is it?

@rossiniscarface
Copy link

how old is windows 7?

@tuyenld
Copy link
Contributor

tuyenld commented Jan 5, 2021

how old is windows 7?

C:\Users\> systeminfo

OS Name:                   Microsoft Windows 7 Ultimate
OS Version:                6.1.7601 Service Pack 1 Build 7601
OS Manufacturer:           Microsoft Corporation
OS Configuration:          Standalone Workstation
OS Build Type:             Multiprocessor Free

Please keep in mind that I am looking for a solution without user intervention.

@cweagans
Copy link

Out of curiosity, why is networking + ssh the chosen route for updates and the like? It seems weird to have a webcam with networking enabled. There might be other purpose-built solutions already available. For instance, the USB DFU protocol could be (ab)used for this purpose. Or possibly expose the rPi as a mass storage device where the user can simply copy a new image into place like normal (at that point, the rPi could dd the image onto the other partition and update the boot partition accordingly).

@htruong
Copy link
Contributor Author

htruong commented Jan 26, 2021

Networking allows us to talk arbitrarily to the camera.

Think of you having to configure or read something about the camera that is beyond conventional controls, it would have been very hard to do so or you'll have to open up a serial console which is confusing and error prone.

For developers, networking will allow you to copy files from and to the camera, this speeds up the development cycle.

You can use dfu mode or mass storage to allow firmware update but making the camera appear as mass storage will just as annoying as making it a network device. And at the same time it serves only one purpose that is to allow you to do upgrades.

@htruong htruong mentioned this pull request Apr 4, 2021
@RoganDawes
Copy link

Possibly a crazy idea, but how about using SSH over the serial port?
SSH just needs a binary clean mechanism to allow it to talk to the daemon, which a serial port is quite capable of providing. Additionally, tools like socat exist which can forward a connection from e.g. stdin or a TCP socket over a serial port (from MacOS or Linux).

The major snag is knowing when to drop the connection, since there is no TCP handshake to indicate a new connection has started, or when it ends.

This can however be simulated by using the serial port flow control lines, which don't exist, technically, but the interfaces for passing them over USB do! So, a tiny program on the Pi opens the serial port, and monitors the DTR flag. When it toggles on, open a new TCP connection to sshd on localhost:22. When it toggles off, close the connection. While it is on, copy bytes from the serial port to the TCP connection, and vice versa.

On the host, one could probably use socat as is, via an ssh ProxyCommand stanza, to redirect the connection via the serial port. One could even make use of the ssh ControlMaster functionality to allow multiplexing ssh connections over the single serial port!

I suspect that should even work on Windows, although perhaps a little more work to get set up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants