树莓派折腾系列

文章更新

  1. 20160526-更新BT SYNC和使用静态IP地址
  2. 20160613-更新了使用DNSPOD更新域名A记录的方式更新外网域名访问
  3. 20160623-更新挂载硬盘、格式化等方法
  4. 20160712-BT SYNC独立成文

折腾1:安装BT SYNC

文章独立分拆,转移到这里→新入口

折腾2:配置公网IP地址(放弃)

配置过程颇费了一番周折,感觉最有价值的参考文章应该还是这篇,所以这里为了尊重作者,链接表示感谢。

自己用的北京联通,虽然拨号会得到公网IP地址,但是每次拨号都会变化,所以需要利用DDNS来将公网域名和内网的IP地址联在一起,看了几个,还是花生壳比较靠谱。

配置DDNS花生壳

因为我有了一个OPWENWRT的路由器,所以可以把花生壳安装在路由器上,步骤很简单,关键是免费的树莓派账号需要花6块钱开通一个“内网穿透”的套餐,然后每一个月1G的流量足够了,因为使用来管理的,又不需要通过这个IP地址来发送接收很多的东西。

准确的说,这里说的方法,并不是给树莓派配置花生壳,而是在OP路由器下运行花生壳,让OP路由器拨号的宽带与一个VICP.NET花生壳域名绑定。

首先到花生壳网站上,注册一个免费账号,选一个你喜欢的域名,然后在OP路由器下的-系统-动态DDNS 下开启花生壳,然后应用运行,如果你在其它地方可以ping到你的花生壳域名,并且返回的IP地址,和你在OP路由上获得WAN口IP地址一致,恭喜你,花生壳运行成功了。

我这里因为用了多拨,虚拟出来了多个WAN口,在OP里,需要指定这个花生壳绑定在哪个具体的WAN口上。

然后还有重要的一点,就是需要在多拨的负载均衡设置里面,将树莓派的静态IP地址,指定某个WAN口作为流量出入口(这条是否必须有待验证,因为我之前挂赚钱宝的习惯,所以才有了这条)。

树莓派使用静态IP地址(错误方法)

这里的方法是错误的,但是我又不忍心删掉了,大家看到的时候,千万记得,这是错的,这是错的,这是错的,重要的事情说三遍。

1
2
3
cd /etc/network
cp interfaces interfaces.bak #备份下
sudo vim interfaces

奇葩的是,π竟然默认没有安装VIM,用了两下VI,觉得实在是不习惯。

安装VIM:

1
sudo apt-get install vim

iface eth0 inet dhcp 这句注释掉,然后按照下面的修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
iface eth0 inet static
address 192.168.10.173 #这是我的IP地址,请按照具体情况修改,下同
netmask 255.255.255.0
gateway 192.168.10.1
```

然后删除 `iface default inet dhcp` 行

否则 ip 是固定的但是无法连外网

然后重启系统

``` bash
sudo reboot

或者重启服务

1
sudo service networking restart

如想修改DNS,则需要修改文件 /etc/resolv.conf

1
2
3
4
5
nameserver 8.8.8.8
nameserver 8.8.4.4
nameserver 208.67.220.220
nameserver 208.67.222.222
nameserver 10.10.10.10

同样也是重启系统或者网络生效。

树莓派使用静态IP地址(正确方法)

网上看了一些文章,发现上一小节中的设置方法网上很泛滥,但是实际上却不是最新的方法,在 /etc/network/interfaces 文件中有这么一句话

# Please note that this file is written to be used with dhcpcd
# For static IP, consult /etc/dhcpcd.conf and ‘man dhcpcd.conf’

已经告诉大家interfaces中的设置并不是用来设置静态IP的,所以我又默默的把interfaces文件恢复原状了。

这个作者在自己的博客上公布了中文版的方法,地址在这里

我顺便总结一下

/etc/dhcpcd.conf文件后面增加

1
2
3
4
5
interface eth0
static ip_address=192.168.10.173/24
static router=192.168.10.1
static gateway=192.168.10.1
static domain_name_servers=192.168.10.1

这里eth0代表板子上的RJ45口的地址

这里要注意 ip地址要根据自己的子网掩码改 而且后面的”/24”也别落下(开始我觉得没用去掉了就不行) 然后domain_name_servers后面还可以加dns地址比如

1
domain_name_servers=192.168.10.1 8.8.8.8

如果使用无线网卡的 可以再加一套

1
2
3
4
interface wlan0
static ip_address=192.168.10.174/24
static routers=192.168.10.1
static domain_name_servers=192.168.10.1

然后创建 /etc/wpa.conf 文件:

1
sudo vim /etc/wpa.conf
  1. 如果你的wifi没有密码

    1
    2
    3
    4
    network={
    [Tab] ssid="你的无线网络名称(ssid)"
    [Tab] key_mgmt=NONE
    }
  2. 如果你的wifi使用WEP加密

    1
    2
    3
    4
    5
    network={
    [Tab] ssid="你的无线网络名称(ssid)"
    [Tab] key_mgmt=NONE
    [Tab] wep_key0="你的wifi密码"
    }
  3. 如果你的wifi使用WPA/WPA2加密

    1
    2
    3
    4
    5
    network={
    [Tab] ssid="你的无线网络名称(ssid)"
    [Tab] key_mgmt=WPA-PSK
    [Tab] psk="你的wifi密码"
    }

注1:所有符号都是半角符号(英文状态下的符号),“[Tab]”表示按一次Tab键

注2:如果你不清楚wifi的加密模式,可以在安卓手机上用root explorer打开 /data/misc/wifi/wpa/wpa_supplicant.conf,查看wifi的信息。

比如,我的wpa.conf文件是这样的:

1
2
3
4
5
network={
    ssid="NETGEAR"
    key_mgmt=WPA-PSK
    psk="PASSWORD"
}

最后输入命令启用无线网卡:

1
sudo ifup wlan0

可以连无线网了。

重启网络服务

1
2
sudo systemctl daemon-reload
sudo service networking restart

系统 2016-05-10-raspbian-jessie

最后,你就可以在INTERNET上,通过 ssh pi@yourdomain.vicp.net 来登录树莓派了。

折腾3:SSH访问OPENWRT路由器

这个本来不应该写在这里的,不过弄完了π也一起弄得op,所以就先记载在这里吧。

修改SSH服务器Dropbear设置

这个步骤不是必须的,详见《OpenWrt SSH远程端口转发》

在OP路由器中的LuCI中选择 系统 –> 管理,勾选 Allow remote hosts to connect to local SSH forwarded ports 选项,保存并应用。

也可以直接修改 Dropbear 配置文件 /etc/config/dropbear

加上一句

1
option GatewayPorts 'on'

修改OP防火墙设置

在OP路由器的 LuCI 中选择 网络 –> 防火墙 –> Traffic RulesNameSSHProtocolTCPExternal port 选 22,保存并应用。

也可以直接修改防火墙配置文件vim /etc/config/firewall

1
2
3
4
5
6
config rule
option target 'ACCEPT'
option src 'wan'
option proto 'tcp'
option dest_port '22'
option name 'SSH'

最后提醒一点,在修改SSH和防火墙设置之前,请设置一个复杂的密码,切记。

折腾4:使用DNSPOD更新外网域名A记录

因为我不小心删掉了OP路由器里面关于ORAY的配置,一时间不知道咋办了,就只能暂时换个办法来设置公网域名访问。

找个便宜域名,让树莓派自己更新某域名的 A RECORD 即可,我在 NAMECHEAP 用0.88美金买了个域名,然后发现无法因为消费太少,而不能使用系统自带的ADVANCED DNS服务。当时想的是,采用API的方式自动更新域名记录,NAMECHEAP不行,就只好找其他DNS服务提供商了,后来发现RAGE4好像是免费的,但是申请了之后,需要等待24小时激活,就没等RAGE4批准。

一直以为DNSPOD的域名解析也需要备案,后来才知道,只有域名指向了国内主机空间A记录才需要域名备案,指向其他国外IP地址是不需要备案的,并且最重要的是,DNSPOD有域名的API SDK,正好符合我的使用条件。

我下面的这段PYTHON代码,是从官方抄来的,地址在这里。循环间隔30秒查询一次π获得IP地址与域名的A记录是否一致,如果不一致,就更新域名的A记录。但是我觉得这个频率有点高,并且DNSPOD的免费套餐,1分钟最多30次更新域名解析记录,我也不想超过这个标准。修改成了采用crontab每2分钟执行一次这个脚本的方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#!/usr/bin/env python
#-*- coding:utf-8 -*-

import httplib, urllib
import socket
import time

params = dict(
login_email="dns email address", # 这里替换成你的DNSPOD登录账号
login_password="dns password", # 这里是密码
format="json",
domain_id=39421602, # 替换成你需要更改的域名的 domain_id, 可以通过 API Domain.List 获得
record_id=197443695, # 替换成你需要更改域名的 record_id, 可以通过 API Record.List 获得
sub_domain="www", # 替换成你想修改的子域名
record_line="默认",
)
current_ip = None

def ddns(ip):
params.update(dict(value=ip))
headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/json"}
conn = httplib.HTTPSConnection("dnsapi.cn")
conn.request("POST", "/Record.Ddns", urllib.urlencode(params), headers)

response = conn.getresponse()
print response.status, response.reason
data = response.read()
print data
conn.close()
return response.status == 200

def getip():
sock = socket.create_connection(('ns1.dnspod.net', 6666))
ip = sock.recv(16)
sock.close()
return ip

if __name__ == '__main__':
try:
ip = getip()
print ip
if current_ip != ip:
if ddns(ip):
current_ip = ip
except Exception, e:
print e
pass

替换上面脚本中的内容即可,想说的是,

domain id 和 record id 也可以分别通过下面的命令行方式获取,直观一些。

1
curl -k https://dnsapi.cn/Domain.List -d "login_email=xxx&login_password=xxx"
1
curl -k https://dnsapi.cn/Record.List -d "login_email=xxx&login_password=xxx&domain_id=xxx"

然后,在树莓派的crontab里加入这样一句话即可

1
*/2 0 * * * /usr/bin/python /usr/test2.py

这里需要注意几点:

  1. 在crontab命令中的环境变量和命令行方式并不一致,所以,最好加上执行命令的全部路径。
  2. 还需要通过 sudo su 的方式,切换到root用户下执行 crontab -e,否则修改的pi用户的crontab,效果就达不到了。
  3. 最后通过 /etc/init.d/cron restart 来重启crontab
  4. cron有两个位置,一个是系统的cron定时任务,文件在 /etc/crontab ,而每个用户的cron,则位于 /var/spool/cron/crontabs/ 目录下,每个用户(pi ,root)分别有cron定时任务的。

系统cron和crontab的重启命令并不相同

对于系统cron

sudo systemctl status cron //查看状态
sudo systemctl start cron //启动服务
sudo systemctl stop cron //停止服务
sudo systemctl restart cron //重启服务

对于每个用户的crontab

/sbin/service crond start 启动
/sbin/service crond stop 停止
/sbin/service crond restart 重启服务
/sbin/service crond reload 重新加载配置

如果直接使用 crontab -e 打开的cron定时任务文件并不是 /etc/crontab ,而是在 /var/spool/cron/crontabs/ 目录下的文件:pi ,root 。每个用户(pi ,root)分别有cron定时任务的。

关于这个的具体说明,可以看这个帖子

上面讨论的东西,可能和这个主题帖关系不大,却很重要,所以单独另外开了一个帖子《关于cron和crontab的那些事》来系统的总结下关于cron和crontab的内容。

折腾5:用树莓派GPIO控制PC电源开关

这个先写在这里吧,最近几天的想法,主要是因为我的技嘉主板BM5-HD3的WOL功能貌似不好用,只要电源关机或者休眠,网卡灯也一起跟着灭了,弄得我只要不在电脑旁边,就无法开机。然后发现可以使用键盘鼠标或者电源按钮唤醒,然后就当然有了这个折腾了。正在搞,回来总结一下。

折腾6:硬盘格式化、挂载

把U盘或者硬盘接在USB扣上,然后运行df -h,

最后那个200多G的就是接的移动硬盘,这个时候可以通过

1
2
sudo mkdir /mnt/hd250g #建立个目录
sudo mount /dev/sda1 /mnt/hd250g #把sda1和hd250g连接起来

如何自动挂载硬盘?

使用 sudo vim /etc/fstab,可以看到下面这样的内容:

1
2
3
4
5
6
proc            /proc           proc    defaults          0       0
/dev/mmcblk0p1 /boot vfat defaults 0 2
/dev/mmcblk0p2 / ext4 defaults,noatime 0 1
/dev/sda1 /home/pi/samba ext4 defaults 0 0
# a swapfile is not a swap partition, no line here
# use dphys-swapfile swap[on|off] for that

指定 fdisk -l(或者 sudo blkid 命令) 中看到的硬盘盘符并且指定挂载的位置,树莓派开机之后,就能自动挂载了。

然后就遇到了这个错误,

1
2
3
Mount is denied because the NTFS volume is already exclusively opened.
The volume may be already mounted, or another software may use it which
could be identified for example by the help of the 'fuser' command.

先卸载了,sudo umount -fl /dev/sda1

因为我这个外接硬盘之前都是用在windows系统下,用的NTFS分区,而linxu一般用的是ext2 ext3 ext4分区。

还有一个挂载硬盘更为稳妥的方式,使用 sudo blkid 命令查看硬盘的UUID,然后在 vim /etc/fstab 中,直接填写UUID="XXX"即可,这种方式,可以保证在有多个硬盘的情况下,硬盘加载的顺序不会乱。

至于格式化,一句话

1
sudo mkfs -t ext4 /dev/sda1

折腾7:树莓派 samba 共享

为了方便的共享树莓派上下载的资源,在树莓派上配置 Samba 服务是很好的选择。

安装 samba:

1
2
sudo apt-get update
sudo apt-get install samba

调整设置:

1
sudo vim /etc/samba/smb.conf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[global]
workgroup = WORKGROUP
security = user
unix password sync = no
socket options = TCP_NODELAY
[homes]
comment = Home Directories
browseable = no
read only = no
create mask = 0600
directory mask = 0700
valid users = %S
[media]
comment = Raspberry Pi SMB
path = /media/PI
browseable = yes
writeable = yes
create mask = 0600
directory mask = 0700
guest ok = yes

global 域下的 socket options 设置为 TCP_NODELAY 可以得到更好的性能。homes 域泛解析所有的用户目录,当有连接请求时,所有的域名称都会被检索,如果有和用户名相同的域名称,那么该域下的设置将替代 homes 域被解析,如果没有,那么 homes 域的设置将单独被解析。homes 域未设定 path 时默认为用户的 home 目录,browseable = no 表示 homes 作为共享目录名是被隐藏的,而无论 browseable 设置为 yes 还是 no,每个用户的用户名都是作为共享目录名存在的。

samba 的用户权限要过两关,首先是满足 samba 的设置设定的权限,其次是遵循 Linux 文件系统的权限。media 域设置了包括 guest 用户在内的所有用户都有读写权限,但是实际上只有满足 /media/PI 文件系统权限设定的用户才有真正的写权限,这么设置最终造成:/media/PI 文件系统设定的属主、组等有相应权限,比如写,其余用户只有读权限。

为 samba 共享设置密码:

1
sudo smbpasswd -a pi

另外,也可以设置 samba 以 xinetd 的方式按需启动,节省资源:

1
sudo vim /etc/xinetd.d/netbios-ssn
1
2
3
4
5
6
7
8
9
10
service netbios-ssn
{
disable = no
socket_type = stream
protocol = tcp
wait = no
user = root
server = /usr/sbin/smbd
instances = 5
}
1
sudo vim /etc/xinetd.d/netbios-ns
1
2
3
4
5
6
7
8
9
10
service netbios-ns
{
disable = no
socket_type = dgram
protocol = udp
wait = yes
user = root
server = /usr/sbin/nmbd
instances = 1
}

移除 samba 按 init 的方式启动:

1
sudo update-rc.d samba remove

至于在 /etc/init.d/ 的自动启动脚本,我黏贴在这里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/bin/sh

### BEGIN INIT INFO
# Provides: samba
# Required-Start:
# Required-Stop:
# Default-Start:
# Default-Stop:
# Short-Description: ensure Samba daemons are started (nmbd and smbd)
### END INIT INFO

set -e

# start nmbd, smbd and samba-ad-dc unconditionally
# the init scripts themselves check if they are needed or not
case $1 in
start)
/etc/init.d/nmbd start
/etc/init.d/smbd start
/etc/init.d/samba-ad-dc start
;;
stop)
/etc/init.d/samba-ad-dc stop
/etc/init.d/smbd stop
/etc/init.d/nmbd stop
;;
reload)
/etc/init.d/smbd reload
;;
restart|force-reload)
/etc/init.d/nmbd "$1"
/etc/init.d/smbd "$1"
/etc/init.d/samba-ad-dc "$1"
;;
status)
status=0
NMBD_DISABLED=`testparm -s --parameter-name='disable netbios' 2>/dev/null || true`
SERVER_ROLE=`samba-tool testparm --parameter-name="server role" 2>/dev/null | tail -1 || true`
if [ "$SERVER_ROLE" != "active directory domain controller" ]; then
if [ "$NMBD_DISABLED" != "Yes" ]; then
/etc/init.d/nmbd status || status=$?
fi
/etc/init.d/smbd status || status=$?
else
/etc/init.d/samba-ad-dc status || status=$?
fi
exit $status
;;
*)
echo "Usage: /etc/init.d/samba {start|stop|reload|restart|force-reload|status}"
exit 1
;;
esac

大家需要的话,可以去我的 github 里面的 randomfiles 库找,具体文件的地址在这里

发现就算在路由器上开了445和139端口,外网也是不能访问SAMBA共享,所以,只能先暂时安装个VPN,先拨号进去VPN,然后就可以访问SAMBA资源了。具体见折腾9:为树莓派安装VPN支持。

折腾8:获得正确的系统时间

在树莓派上打 date 命令可以查看系统的日期时间。由于树莓派没有电池,关机后彻底断电,无法保存时间。树莓派默认安装了 NTP(Network Time Protocol)服务来获取互联网上ntp服务器提供的时间。如果这个时间不准,可以用这个命令校准一下:

1
sudo ntpd -s -d

如果时间还是不准确,就用下面命令强制校准

1
sudo date --s="2016-06-22 12:22:00"

如果校准了之后,发现时间还是不对,可以先不用强制校准,毕竟这个方法时间不准确,通过

1
sudo raspi-config

修改international设置,来设置下市区,选择 Asia - Shanghai 即可,然后重新校准时间。

如果上面的方法校准后,还不行,说明树莓派没有正确的连接NTP服务器。

打开NTP服务配置文件

1
sudo nano /etc/ntp.conf

找到以下两行

1
2
# You do need to talk to an NTP server or two (or three).
# server ntp.your-provider.example

然后在下面添加以下内容,是一些亲测可用的 NTP 服务器。第一行最后的perfer表示优先使用此服务器,也就是复旦大学的 NTP 服务器。添加之后按 Ctrl + X 保存退出。

1
2
3
4
5
server ntp.fudan.edu.cn iburst perfer
server time.asia.apple.com iburst
server asia.pool.ntp.org iburst
server ntp.nict.jp iburst
server time.nist.gov iburst

最后,重启 NTP 服务w

1
sudo /etc/init.d/ntp restart

参考资料

安装samba实现文件共享
树莓派教程:配置 Samba 局域网共享

折腾10:ARIA2 远程下载

分享到