Skip to content

Commit

Permalink
First commit
Browse files Browse the repository at this point in the history
  • Loading branch information
schollz committed Feb 17, 2018
0 parents commit b80fc84
Show file tree
Hide file tree
Showing 7 changed files with 327 additions and 0 deletions.
98 changes: 98 additions & 0 deletions README.md
@@ -0,0 +1,98 @@
# Instructions for making a turn-key image

## Flash Raspbian Stretch Lite

Starting from version [Raspbian Stretch Lite](https://www.raspberrypi.org/downloads/raspbian/) version 2017-11-29.

```
sudo dd bs=4M if=2017-11-29-raspbian-stretch-lite.img of=/dev/mmcblk0 conv=fsync status=progress
```

Change `/dev/mmcblk0` to whatever your SD card is (find it using `fdisk -l`).

After flashing, for the first time use, just plug in ethernet and you can SSH into the Pi. To activate SSH on boot just do

```
touch /media/YOURUSER/boot/ssh
```

## Add libraries onto the Pi

```
sudo apt-get update
sudo apt-get dist-upgrade -y
sudo apt-get install -y dnsmasq hostapd vim python3-flask git
```

## Install node

```
wget https://nodejs.org/dist/v8.9.4/node-v8.9.4-linux-armv6l.tar.xz
sudo mkdir /usr/lib/nodejs
sudo tar -xJvf node-v8.9.4-linux-armv6l.tar.xz -C /usr/lib/nodejs
rm -rf node-v8.9.4-linux-armv6l.tar.xz
sudo mv /usr/lib/nodejs/node-v8.9.4-linux-armv6l /usr/lib/nodejs/node-v8.9.4
echo 'export NODEJS_HOME=/usr/lib/nodejs/node-v8.9.4' >> ~/.profile
echo 'export PATH=$NODEJS_HOME/bin:$PATH' >> ~/.profile
source ~/.profile
```

## Install Go

```
wget https://dl.google.com/go/go1.10.linux-armv6l.tar.gz
sudo tar -C /usr/local -xzf go*gz
rm go*gz
echo 'export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin' >> ~/.profile
echo 'export GOPATH=$HOME/go' >> ~/.profile
source ~/.profile
```

# Install base station

```
git clone https://github.com/schollz/raspberry-pi-turnkey.git
```

# Install Hostapd

```
sudo systemctl stop dnsmasq && sudo systemctl stop hostapd
echo 'interface wlan0
static ip_address=192.168.4.1/24' | sudo tee --append /etc/dhcpcd.conf
sudo mv /etc/dnsmasq.conf /etc/dnsmasq.conf.orig
sudo systemctl daemon-reload
sudo systemctl restart dhcpcd
echo 'interface=wlan0
dhcp-range=192.168.4.2,192.168.4.20,255.255.255.0,24h' | sudo tee --append /etc/dnsmasq.conf
echo 'interface=wlan0
driver=nl80211
ssid=ConnectToConnect
hw_mode=g
channel=7
wmm_enabled=0
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=ConnectToConnect
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP
rsn_pairwise=CCMP' | sudo tee --append /etc/hostapd/hostapd.conf
echo 'DAEMON_CONF="/etc/hostapd/hostapd.conf"' | sudo tee --append /etc/default/hostapd
sudo systemctl start hostapd && sudo systemctl start dnsmasq
```

Add to cron

```
@reboot cd /home/pi/raspberry-pi-turnkey && /usr/bin/sudo /usr/bin/python3 startup.py
```


15 changes: 15 additions & 0 deletions disable_ap.sh
@@ -0,0 +1,15 @@
#!/bin/bash

sleep 3

# disable the AP
sudo sed -i '/DAEMON_CONF="\/etc/s/^/#/g' /etc/default/hostapd
sudo sed -i '/interface wlan0/s/^/#/g' /etc/dhcpcd.conf
sudo sed -i '/static ip_address=192.168.4.1\/24/s/^/#/g' /etc/dhcpcd.conf
sudo sed -i '/interface=wlan0/s/^/#/g' /etc/dnsmasq.conf
sudo sed -i '/dhcp-range=/s/^/#/g' /etc/dnsmasq.conf

# load wlan configuration
sudo cp wpa.conf /etc/wpa_supplicant/wpa_supplicant.conf

sudo reboot now
9 changes: 9 additions & 0 deletions enable_ap.sh
@@ -0,0 +1,9 @@
#!/bin/bash

sudo sed -i '/DAEMON_CONF="\/etc/s/^#//g' /etc/default/hostapd
sudo sed -i '/interface wlan0/s/^#//g' /etc/dhcpcd.conf
sudo sed -i '/static ip_address=192.168.4.1\/24/s/^#//g' /etc/dhcpcd.conf
sudo sed -i '/interface=wlan0/s/^#//g' /etc/dnsmasq.conf
sudo sed -i '/dhcp-range=/s/^#//g' /etc/dnsmasq.conf

sudo reboot now
62 changes: 62 additions & 0 deletions startup.py
@@ -0,0 +1,62 @@
import subprocess
import re
import json
import os.path

from flask import Flask, request, send_from_directory,jsonify, render_template
app = Flask(__name__, static_url_path='')

wpa_conf = """country=GB
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
ssid="_ssid_"
psk="_password_"
}"""

@app.route('/')
def main():
return render_template('index.html')

@app.route('/static/<path:path>')
def send_static(path):
return send_from_directory('static', path)

@app.route('/signin', methods=['POST'])
def signin():
email = request.form['email']
ssid = request.form['ssid']
password = request.form['password']
print(email,ssid,password)
with open('wpa.conf','w') as f:
f.write(wpa_conf.replace('_ssid_',ssid).replace('_password_',password))
with open('status.json','w') as f:
f.write(json.dumps({'status':'disconnected'}))
subprocess.Popen(["./disable_ap.sh"])
return render_template('index.html', message="You are signed in. Please wait 2 minutes and then check your email for the link.")

if __name__ == "__main__":
# get status
s = {'status':'disconnected'}
if not os.path.isfile('status.json'):
with open('status.json','w') as f:
f.write(json.dumps(s))
else:
s = json.load(open('status.json'))

# check connection
result = subprocess.run(['iwconfig', 'wlan0'], stdout=subprocess.PIPE)
matches=re.findall(r'\"(.+?)\"',result.stdout.split(b'\n')[0].decode('utf-8'))
if len(matches) > 0:
s['status'] = 'connected'
print("got connected to " + matches[0])

if s['status'] == 'disconnected':
s['status'] = 'hostapd'
with open('status.json','w') as f:
f.write(json.dumps(s))
subprocess.call("./enable_ap.sh", shell=True)
elif s['status'] == 'connected':
pass
else:
app.run(host="0.0.0.0",port=80)
7 changes: 7 additions & 0 deletions static/bootstrap.min.css

Large diffs are not rendered by default.

87 changes: 87 additions & 0 deletions static/floating-labels.css
@@ -0,0 +1,87 @@
:root {
--input-padding-x: .75rem;
--input-padding-y: .75rem;
}

html,
body {
height: 100%;
}

body {
display: -ms-flexbox;
display: -webkit-box;
display: flex;
-ms-flex-align: center;
-ms-flex-pack: center;
-webkit-box-align: center;
align-items: center;
-webkit-box-pack: center;
justify-content: center;
padding-top: 40px;
padding-bottom: 40px;
background-color: #f5f5f5;
}

.form-signin {
width: 100%;
max-width: 420px;
padding: 15px;
margin: 0 auto;
}

.form-label-group {
position: relative;
margin-bottom: 1rem;
}

.form-label-group > input,
.form-label-group > label {
padding: var(--input-padding-y) var(--input-padding-x);
}

.form-label-group > label {
position: absolute;
top: 0;
left: 0;
display: block;
width: 100%;
margin-bottom: 0; /* Override default `<label>` margin */
line-height: 1.5;
color: #495057;
border: 1px solid transparent;
border-radius: .25rem;
transition: all .1s ease-in-out;
}

.form-label-group input::-webkit-input-placeholder {
color: transparent;
}

.form-label-group input:-ms-input-placeholder {
color: transparent;
}

.form-label-group input::-ms-input-placeholder {
color: transparent;
}

.form-label-group input::-moz-placeholder {
color: transparent;
}

.form-label-group input::placeholder {
color: transparent;
}

.form-label-group input:not(:placeholder-shown) {
padding-top: calc(var(--input-padding-y) + var(--input-padding-y) * (2 / 3));
padding-bottom: calc(var(--input-padding-y) / 3);
}

.form-label-group input:not(:placeholder-shown) ~ label {
padding-top: calc(var(--input-padding-y) / 3);
padding-bottom: calc(var(--input-padding-y) / 3);
font-size: 12px;
color: #777;
}
49 changes: 49 additions & 0 deletions templates/index.html
@@ -0,0 +1,49 @@

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="">
<meta name="author" content="">

<title>Sign In</title>

<!-- Bootstrap core CSS -->
<link href="/static/bootstrap.min.css" rel="stylesheet">

<!-- Custom styles for this template -->
<link href="/static/floating-labels.css" rel="stylesheet">
</head>

<body>
<form class="form-signin" action="/signin" method="POST">
<div class="text-center mb-4">
<!-- <img class="mb-4" src="https://getbootstrap.com/assets/brand/bootstrap-solid.svg" alt="" width="72" height="72">
-->
<h1 class="h3 mb-3 font-weight-normal">Sign in</h1>
{% if message %}<p>{{ message }}</p>{% endif %}
</div>

{% if message %}{% else %}
<div class="form-label-group">
<input type="email" name="email" id="inputEmail" class="form-control" placeholder="Email address" required autofocus>
<label for="inputEmail">Email address</label>
</div>

<div class="form-label-group">
<input name="ssid" id="inputSSID" class="form-control" placeholder="SSID" required>
<label for="inputPassword">SSID</label>
</div>


<div class="form-label-group">
<input id="inputPassword" name="password" class="form-control" placeholder="SSID Password" required>
<label for="inputPassword">Password</label>
</div>

<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
{% endif %}
<p class="mt-5 mb-3 text-muted text-center"><a href="https://github.com/schollz/raspberry-pi-turnkey">Raspberry Pi Turnkey</a></p>
</form>
</body>

0 comments on commit b80fc84

Please sign in to comment.