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

Building and running on Raspberry Pi #27

Open
NickSutton opened this issue Apr 14, 2018 · 45 comments
Open

Building and running on Raspberry Pi #27

NickSutton opened this issue Apr 14, 2018 · 45 comments

Comments

@NickSutton
Copy link

Hi, trying to get Grumble up and running on the Pi so I can leverage the websockets functionality.

The install go get mumble.info/grumble/cmd/grumble Fails on a $GOPATH not set error, even when $GOPATH is explicitly set before hand and can be seen in go env

Could someone let me know what I’ve missed?

@ghost
Copy link

ghost commented Apr 14, 2018

What's the output of go env?

@NickSutton
Copy link
Author

NickSutton commented Apr 14, 2018

Thank Tim,

GOARCH="arm"
GOBIN=""
GOEXE=""
GOHOSTARCH="arm"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/pi/gocode"
GORACE=""
GOROOT="/usr/lib/go-1.7"
GOTOOLDIR="/usr/lib/go-1.7/pkg/tool/linux_arm"
CC="gcc"
GOGCCFLAGS="-fPIC -marm -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-abuild589052819=/tmp/go-build -gno-record-gcc-switches"
CXX="g++"
CGO_ENABLED="1"

@ghost
Copy link

ghost commented Apr 14, 2018

Not sure why you're seeing that error, but Go 1.7 is a few versions behind. It might be worthwhile to upgrade to Go 1.10 and then try to build grumble.

@NickSutton
Copy link
Author

Cancel last! Was running with sudo so perhaps it was unhappy with the pi username?

Anyway, install out put gave this, is this a fail or information warnings: go get mumble.info/grumble/cmd/grumble

mumble.info/grumble/cmd/grumble

../pi/gocode/src/mumble.info/grumble/cmd/grumble/server.go:1457: unknown http.Server field 'IdleTimeout' in struct literal
../pi/gocode/src/mumble.info/grumble/cmd/grumble/server.go:1461: undefined: http.ErrServerClosed
../pi/gocode/src/mumble.info/grumble/cmd/grumble/server.go:1522: server.webhttp.Shutdown undefined (type *http.Server has no field or method Shutdown)`

Thanks for your quick help!

@ghost
Copy link

ghost commented Apr 14, 2018

Those errors are related to the Go version. Upgrade to 1.10 and they should go away.

@NickSutton
Copy link
Author

OK, will try that. Installing Go on the Pi is a pain!!

@NickSutton
Copy link
Author

NickSutton commented Apr 14, 2018

Awesome, perfect install. For anyone else going down this route, here are the instructions for GoLang 1.10 on Pi (lifted from elsewhere on Git)

To install golang 1.10 (or whatever the latest version is at the time anyone is reading this):

wget https://storage.googleapis.com/golang/go1.10.linux-armv6l.tar.gz
sudo tar -C /usr/local -xvf go1.10.linux-armv6l.tar.gz
cat >> ~/.bashrc << 'EOF'
export GOPATH=$HOME/go
export PATH=/usr/local/go/bin:$PATH:$GOPATH/bin
EOF
source ~/.bashrc

Run go version to check and you should see output of: go version g1.10 linux/arm also this preserves /usr/bin/go is you installed it previously.

Now, excuse my blatant lack of knowledge, but what next? Does this sit on top of a mumble-server install or instead? I’ve just removed a working mumble and hope for grumble to take its place!

UPDATE:

Following reboot, setup GOPATH
$ export GOPATH=$HOME/gocode
$ mkdir -p $GOPATH

Then run the following line:
$ go get mumble.info/grumble/cmd/grumble

CD in to GOPATH/src/mumble.info/grumble/cmd/grumble and make any config changes you need before building the program: go build -o grumble mumble.info/grumble/cmd/grumble

And check ./grumble —help this will expose the various command line switches, you will need to populate at least the following:

./grumble --datadir ~/gocode --log ~/gocode/log

@ghost
Copy link

ghost commented Apr 14, 2018

Does this sit on top of a mumble-server install or instead?

The latter; grumble is a separate, standalone Mumble server. After starting grumble, you should be able to connect to your Pi from your Mumble client.

@NickSutton
Copy link
Author

I thought so... That’s it!? So simple... Where is the configuration to add my password and define port etc?

@ghost
Copy link

ghost commented Apr 14, 2018

Configuration is currently unmerged in PR #26. In the mean time, you can manually apply that patch to your local copy to enable configuration.

@NickSutton
Copy link
Author

Wow, look like you guys have done a lot of work, and I’ve got a lot of learning to do! I wish someone had travelled this path before me (and documented it along the way!)

How do i start Grumble?

@ghost
Copy link

ghost commented Apr 14, 2018

Thanks for being a trailblazer.

After building grumble (go build -o grumble mumble.info/grumble/cmd/grumble), just run it (./grumble). You may have to play around with the arguments (pass --help to see available ones).

@NickSutton
Copy link
Author

Thanks - I’m getting there... but you’re definitely right about the arguments!!

`go run grumble.go --help

command-line-arguments

./grumble.go:25:5: undefined: Args
./grumble.go:26:3: undefined: Usage
./grumble.go:31:26: undefined: Args
./grumble.go:33:56: undefined: Args
./grumble.go:39:34: undefined: Args
./grumble.go:41:62: undefined: Args
./grumble.go:48:41: undefined: Args
./grumble.go:56:27: undefined: Args
./grumble.go:68:26: undefined: Args
./grumble.go:69:25: undefined: Args
./grumble.go:69:25: too many errors
`

@ghost
Copy link

ghost commented Apr 14, 2018

The --help flag is mean for the compiled grumble binary, not go run.

You should also use go build to compile grumble -- go run isn't straightforward with respect to how grumbles files are organized.

@NickSutton
Copy link
Author

Yep, go build command seemed to execute without any issue. ./grumble wasn’t working though so i tried grumble.go but no dice.?

Does ./grumble need to be from a specific directory?

@ghost
Copy link

ghost commented Apr 14, 2018

if you passed -o grumble to go build, then the grumble binary will appear in your current working directory.

@NickSutton
Copy link
Author

Yes, did that. Can see the binary, but ./grumble gives Unable to open data directory (/home/pi/.grumble): open /home/pi/.grumble: no such file or directory

Worth noting home/pi/gocode is current GOPATH Variable

@ghost
Copy link

ghost commented Apr 14, 2018

Those errors are what I was alluding to earlier: you'll have to pass some arguments to grumble, specifically --datadir and --log.

@NickSutton
Copy link
Author

Ok! Got the help text. Is there anywhere I can write this all up for the next Pi guy?

@ghost
Copy link

ghost commented Apr 14, 2018

I'd just leave it in a comment in this thread. We should hopefully get some official docs together in the future.

@ghost ghost changed the title GOPATH Building and running on Raspberry Pi Apr 14, 2018
@NickSutton
Copy link
Author

Ok, well I’d be happy to help!

So here’s where I’m at:

./grumble --datadir ~/gocode --log ~/gocode/log [G] 2018/04/14 13:17:30.342856 Grumble [G] 2018/04/14 13:17:30.343374 Using data directory: /home/pi/gocode [G] 2018/04/14 13:17:30.343782 Generating 4096-bit RSA keypair for self-signed certificate... [G] 2018/04/14 13:19:49.679947 Certificate output to /home/pi/gocode/cert.pem [G] 2018/04/14 13:19:49.680261 Private key output to /home/pi/gocode/key.pem [1] 2018/04/14 13:19:49.695490 Started: listening on [::]:64738 and 0.0.0.0:443 [1] 2018/04/14 13:19:49.696451 Fatal HTTP server error: listen tcp 0.0.0.0:443: bind: permission denied

How can I set my IP or, more ideally, domain name

@ghost
Copy link

ghost commented Apr 14, 2018

You can either:

  1. Modify the source code to bind your server on a specific IP address and port, or
  2. Locally merge the Config system #26 branch to enable configuration file support where you can set configuration options

@NickSutton
Copy link
Author

Ok, 26 sounds like more flexibility in the long run, but i don’t know how to merge the files in #26.

I can look through the source files and find where to set the IP.
Thanks again for your support

@NickSutton
Copy link
Author

Tried to merge the file changes on local machine and rebuild, once I fixed all my typos I’m still getting errors about a missing ini package “gopkg.in/ini.v1" from the new file_ini.go file . Do I need a template configuration in .ini format?

@rubenseyer
Copy link
Contributor

The config support adds a new external dependency, so you may have to go get gopkg.ini/ini.v1 to be able to build it. A template configuration should be automatically created on first run. However, the config support is still WIP and I recommend you merge the new changes in #26 to avoid a persistence issue before you set any config keys.

@NickSutton
Copy link
Author

Thanks, I think I’ll keep an eye on the config support and d/l when it’s part of the git proper.
In the meantime, can you tell me where I can set the domain of my machine, also webport 443 is in use by email SSL, so will need to rename that to be able to connect to websockets?

@rubenseyer
Copy link
Contributor

The reason the default webport is 443 is because that will be required for the planned Let's Encrypt support. Websockets works fine on any port otherwise. Setting the config key webport (if you're on the config branch) or editing line 40 in server.go will do the trick. If you're connecting from a browser, make sure it trusts the certificate that Grumble sends, otherwise the connection will fail.

The default host should work fine in most cases but if you need to set it it's the config key host or line 1384 in server.go.

@mkrautz
Copy link
Contributor

mkrautz commented Apr 15, 2018

On Linux you can only bind to port 443 (really, allow ports <= 1024) as root -- unless you set a capability on the binary.

See for example:
https://unix.stackexchange.com/questions/10735/linux-allowing-an-user-to-listen-to-a-port-below-1024

Personally, I like this method:
https://unix.stackexchange.com/a/10737

@NickSutton
Copy link
Author

NickSutton commented Apr 15, 2018

That looks pretty advanced. 443 isnt that much of an issue to me as I can reallocate the email port, and I’m not really sure it’s a problem.

Got the script to recognise my IP now, but still have a permission denied message ( Fatal HTTP server error: listen tcp 127.0.0.1:443: bind: address already in use) for binding to 443. Will investigate and update

Update, 443 was in use by Apache2. Changed to 442 and rebuilt, and now:
Started: listening on 127.0.0.1:64738 and 127.0.0.1:442Started: listening on 127.0.0.1:64738 and 127.0.0.1:442 woop!! Just the TLS side of thing to sort out now

@NickSutton
Copy link
Author

NickSutton commented Apr 22, 2018

Hi All,
Thanks again for the help so far. Is it possible to disable TLS/SSL for testing, I’m having difficulty getting the mumble client to connect with the Grumble generated cert.PEM file, once converted to PKCS12 format. Also, iOS Mumble app requires that certificates are imported from iTunes, which I’ve successfully avoided for nearly 5 years!! Any tips on clients that will use the generated certs, or can it be temporarily disabled?

openssl pkcs12 -export -out certificate.pfx -inkey privateKey.key -in certificate.crt -certfile CACert.crt

@rubenseyer
Copy link
Contributor

I don't quite understand. There should be no need to convert the generated certificate, or import it into the client - it is meant for the server. You can't disable TLS, but nothing says the certificate needs to be trusted by the client (neither the ordinary Mumble protocol on 64738 nor Websockets require this), so the generated certificates should work fine.

Sorry for the vague answer. If you post the exact steps you are taking, I could probably give you a more concrete suggestion.

@NickSutton
Copy link
Author

hi, thanks for reply.
so, all my connections are being refused due to SSL error. thought i might need to import the certificate from the server into the client. followed mumble client server wizard which demands a different format to PEM. A bit stuck know and sense that i am close to being accept a connection!

@rubenseyer
Copy link
Contributor

The client wizard configures the user certificate. Could you please post the exact error message from the client and any relevant logs (if they exist) from Grumble?

@NickSutton
Copy link
Author

Ok, thinking it through, I may be launching grumble and not telling about the certificate with the correct flags! My bad. Will test later

@NickSutton
Copy link
Author

So the mumble client running on another Pi does now connect.
Required to ‘Surpress certificate and password storage’ in network (Advanced) settings, guess there must have been an old one cached or something?

Still no luck from iOS - Getting a connection refused message. Is there a Grumble log that might shed more light on this?

The server running on 127.0.0.1 can still be reached externally with port forwarding cant it? I’ve not changed any port forwarding settings as it worked fine with the mumble server and we are using the same port?..

@rubenseyer
Copy link
Contributor

If you bind to 127.0.0.1 it is only accessible on the loopback interface locally. (It's strange that it is accessible from another Pi.) You have to bind to 0.0.0.0 to listen on all interfaces, which should be reachable externally with port forwarding as usual.

Regarding the need to surpress certificates, maybe the mismatch from the old server certificate caused a security error on the client? I know too little about the mumble client to answer this one.

@NickSutton
Copy link
Author

That makes sense, I’ve gone back to 0.0.0.0 and can now accept connections internally and externally, so that’s great!

Regarding the websockets, has anyone written a client to view the information that is sent from the Grumble Server via WS? I manipulated an existing page, but stuck with an ‘Error during websockets handshake: ERR_INVALID_HTTP_RESPONSE message. I think this is the last piece of the puzzle for me!

Thanks again for all your help so far, I hope this helps other Pi users out!

@rubenseyer
Copy link
Contributor

ERR_INVALID_HTTP_RESPONSE usually indicates you haven't attempted the TLS handshake first – make sure you use the wss:// scheme and not ws:// when connecting. (If you're trying this in a browser, you should receive a 400 bad request when connecting via https - that means the TLS layer is working.) These kinds of errors should generate Grumble log messages however.

I don't know of any easy way to dump the traffic, but once the handshakes are done it's just WS messages containing the binary Mumble protocol.

@NickSutton
Copy link
Author

Ok, changing to wss:// changes the error code to ERR_INSECURE_RESPONSE in the browser console.

Do you know what Grumble typically sends out over websockets?

@rubenseyer
Copy link
Contributor

ERR_INSECURE_RESPONSE means the browser doesn't trust the certificate. Since you're using the autogenerated cert, you have to either import the server cert in the browser to make it trusted (complicated, but permanent) or connect over https in the browser window to show Chromes exception ui (fast, but temporary).

I don't understand what you mean by "typically". The websocket messages only wrap the mumble protocol just like the one used over port 64738, nothing more. Grumble doesn't support any sort of RPC yet. If you want to speak the protocol in a browser I'd suggest a library like mumble-client together with mumble-client-websocket (an example built with those is mumble-web).

@NickSutton
Copy link
Author

I’ll look in to that Chromium on Pi seems that little bit more complicated than everything else!

So, with the WebSockets, literally the only reason I’m interested is to see if I can send a message from the server to my mumble clients when a user is transmitting. I hope to display the user ID of the mumble session transmitting on all the other clients. I appreciate this may require a change to the underlying code.

I’m starting to think it might be easier to change the underlying to code to simply write to a log instead, whenever anyone transmits, and use something like WebsocketD to send out the messages whilst parsing the log. I’m not looking to build a mumble web client or anything like that.... Hopefully something much simpler!

@NickSutton
Copy link
Author

I imported the cert and set the websocket JavaScript to connect to wss://127.0.0.1:442 and now it connects. The console shows a ‘blob’ dump, so this is good progress.

How can I edit the binary code to identify the user that is transmitting and send that either over websockets or to log?

@rubenseyer
Copy link
Contributor

Sending extra data over WS requires substantial modifications, as it shares the ordinary mumble protocol implementation. In essence, a WS connection is equivalent to an ordinary user connecting with an ordinary mumble client -- using it for RPC-like tasks is probably more trouble than it's worth. (Unfortunately, Grumble has no RPC support at this moment.) AFAIK, the Mumble protocol has no "talking" state and the server doesn't keep track of this anyway. (Unless you try to build a hack around requesting idle time or something like that, I guess...)

The hacky way closest to what you are describing would be to log the user id for every voice packet received by the server in the udp loops. I guess it would work but you would need to communicate this (quite spammy) info over some other channel. The proper way to solve this is probably modifying your client to expose the talking/silent state based on voice packets being received or not, just like the "standard" Mumble client. That should be compatible with any server speaking the Mumble protocol.

@NickSutton
Copy link
Author

Hey, thanks for the reply. I guess I’m trying to use the WS for something way outside what it was designed for.

Fortunately my client is a GoLang implementation and does already log when the PTT is hit. I didn’t follow this up previously as I’d thought running WS on each client to tell the server something it already knows seemed an untidy way of achieving what i wanted. However, as WS is two way, I guess it’s not actually that bad! I’ll leave the server alone for now and see what can be done from the client...Thanks for all the support here, really good of you guys

@dirkk0
Copy link

dirkk0 commented Nov 24, 2020

I have grumble working on a RaspberryPi3 with LetsEncrype certificates in conjunction with mumble-web, which ran on a different machine. Being new to golang, I tried to document my efforts to get this going in a somewhat hackish way:

a) install golang

sudo apt install golang-go
go version  # gives go1.11.6 linux/arm at the time of this writing

b) build grumble

This should be working now, but we will recompile later in (g)

git clone https://github.com/mumble-voip/grumble.git
cd cmd/grumble
go build

c) create the data directory

mkdir /home/pi/.grumble

d) edit args.go

I hardcoded the datadir to '/home/pi/.grumble' here, since it's not configurable.

This may not be needed, but I wanted to start the server with sudo, which would change home to root, so that was one easy way. Also, comment out the other lines, or go will complain about unused variables and not compile.

e) edit server.go

Hardcode the port here. I chose 9444, and you need to open this port in your router (and maybe also 64738 to connect with a client).

f) copy the keys.

This could probably done in a more elegant way, but I sudo copied the keys to the .grumble directory according to this information. If you don't do this, mumble-web/Chrome will not be able to connect to grumbles web sockets.

sudo su
cp /etc/letsencrypt/live/MYDOMAIN/cert.pem /home/pi/.grumble/cert.pem
cp /etc/letsencrypt/live/MYDOMAIN/privkey.pem /home/pi/.grumble/key.pem

Change MYDOMAIN to your letsencrypt domain name. Note that the clients will be able to connect, but will complain about the certificate. Maybe it would have been better to hardcode the paths to the keys in the the letsencrypt folder, I didn't try this (yet EDIT: tried it, same result).

g) build
Build with cd /home/pi/grumble/cmd/grumble; go build again and start with sudo ./grumble.

You should be able to connect to yourdomain.com with a mumble client and to yourdomain.com:9444 with mumble-web.

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

No branches or pull requests

4 participants