[TOC] # 前提 首先你家里宽带要分配公网ip 我们用路由跟踪命令查看下 ~~~ traceroute baidu.com ~~~ mac是traceroute,linux和windows自己百度路由跟踪命令 可以看出你电脑去百度经过的ip 一般家庭的路由器ip是192.168.0.1或者192.168.1.1 如果分配了公网ip就往下看 ## ios开启ipv6 ios-APN文件 https://www.v2ex.com/amp/t/474539 安卓和电信 https://www.youtube.com/watch?v=09QOuRrYCC0&app=desktop # 进行端口映射 首先我们在外部分配公网ip的那个路由器中设置端口映射 转发规则-虚拟服务器 ![](https://box.kancloud.cn/bb4e3ac0d20ae1b7275468f41a712863_1328x360.png) 由于我家里里面又接入了一个路由器,所以我还有一个路由器要设置端口映射 (建议自己电脑设置静态ip,在路由器那边设置,DHCP) ![](https://box.kancloud.cn/7b9285fd378b4f40269ad0a6fd2266d8_900x160.png) 把上层路由器的端口再映射到我的mac上 # ip分析 ~~~ http://ip.koolcenter.com/all ~~~ # 查询公网ip接入 ## ipv4 试了发现有用的,有可能会没响应 ~~~ curl members.3322.org/dyndns/getip curl http://v4.ipv6-test.com/api/myip.php curl http://ip.koolcenter.com curl ipecho.net/plain curl www.trackip.net/i # 可能需要正则切割下 curl icanhazip.com curl ipinfo.io/ip curl ipecho.net/plain ~~~ 暂时没响应,有时有响应 ~~~ curl curlmyip.com curl ifconfig.me curl ip.appspot.com ~~~ 或者你可以curl路由器,然后正则切割把路由器中的公网ip提取出来 ## ipv6 ~~~ http://v6.ipv6-test.com/api/myip.php ~~~ ## 成品 ~~~ 支持ipv6 https://github.com/NewFuture/DDNS ~~~ ## ip地址查询 ~~~ <?php $ip = @file_get_contents("http://ip.taobao.com/service/getIpInfo.php?ip=".$_GET["ip"]); $ip = json_decode($ip,true); ?> ~~~ 其他的 ~~~ api.help.bj.cn/apis/ip?ip=xx.xx.xx.xx ~~~ http://ip-api.com/json/?fields=520191&lang=zh-CN 获取的数据默认语言可以随便设置,较精确,但是没有城市行政代码 http://pv.sohu.com/cityjson?ie=utf-8 搜狐这个接口很稳定,也会返回城市代码500000,但是有时用4G或者其他情况返回的城市代码为CN,城市名为CHINA,不够精确 # php获取公网ip ~~~ /** * 参数: * * @param string $proxy_override, [true|false], 是否优先获取从代理过来的地址 * @return string * */ function get_client_ip_from_ns($proxy_override = false) { if ($proxy_override) { /* 优先从代理那获取地址或者 HTTP_CLIENT_IP 没有值 */ $ip = empty($_SERVER["HTTP_X_FORWARDED_FOR"]) ? (empty($_SERVER["HTTP_CLIENT_IP"]) ? NULL : $_SERVER["HTTP_CLIENT_IP"]) : $_SERVER["HTTP_X_FORWARDED_FOR"]; } else { /* 取 HTTP_CLIENT_IP, 虽然这个值可以被伪造, 但被伪造之后 NS 会把客户端真实的 IP 附加在后面 */ $ip = empty($_SERVER["HTTP_CLIENT_IP"]) ? NULL : $_SERVER["HTTP_CLIENT_IP"]; } if (empty($ip)) { $ip = $_SERVER['REMOTE_ADDR']; } /* 真实的IP在以逗号分隔的最后一个, 当然如果没用代理, 没伪造IP, 就没有逗号分离的IP */ if ($p = strrpos($ip, ",")) { $ip = substr($ip, $p+1); } return trim($ip); } $rel = get_client_ip_from_ns(); var_dump($rel); ~~~ # 保持存活机制 ## 在linux下使用TCP的keepalive tcp_keepalive_time 一个连接需要TCP开始发送keepalive探测数据包之前的空闲时间。以秒为单位 tcp_keepalive_probes 发送TCP keepalive探测数据包的最大数量,默认是9.如果发送9个keepalive探测包后对端仍然没有响应,就关掉这个连接 tcp_keepalive_intvl 发送两个TCP keepalive探测数据包的间隔时间,默认是75秒 ~~~ $ cat /proc/sys/net/ipv4/tcp_keepalive_time 7200 $ cat /proc/sys/net/ipv4/tcp_keepalive_probes 9 $ cat /proc/sys/net/ipv4/tcp_keepalive_intvl 75 ~~~ 可以通过echo临时修改 ~~~ echo "300" > /proc/sys/net/ipv4/tcp_keepalive_time ~~~ 也可以通过修改/etc/sysctl.conf永久生效 ~~~ $ grep net.ipv4.tcp_keepalive_time /etc/sysctl.conf net.ipv4.tcp_keepalive_time = 300 $ sysctl -p|grep net.ipv4.tcp_keepalive_time net.ipv4.tcp_keepalive_time = 300 ~~~ ## ssh的keepalive SSH连接总是隔一段时间没有输入时就断开,解决办法如下: **服务端配置** ~~~ sudo vim /etc/ssh/sshd_config ClientAliveInterval 60 #服务端主动向客户端请求响应的间隔,数值是秒 ClientAliveCountMax 10 #服务器发出请求后客户端没有响应的次数达到一定值就自动断开 sudo restart ssh ~~~ **客户端配置 ** ~~~ sudo vi /etc/ssh/ssh_config #或~/.ssh/config ~~~ 客户端主动向服务端请求响应的间隔 ServerAliveInterval ~~~ ServerAliveInterval 60 TCPKeepAlive=yes ~~~ 或 ~~~ ssh -i <key-file> -o StrictHostKeyChecking=no -o TCPKeepAlive=yes -o ServerAliveInterval=30 ubuntu@<ip> ~~~ 上面方式任选一种,我选客户端配置方式。 # mac端口转发 找个端口转发工具就可以,我这边用的是rinetd brew下载rinetd,可能需要翻墙 ~~~ brew install rinetd ~~~ 修改配置文件`/usr/local/etc/rinetd.conf` ~~~ # 设置允许访问的ip地址信息 allow * # 9503转发到本机的ssh 0.0.0.0 9503 127.0.0.1 22 # 日志 logfile /usr/local/var/log/rinetd.log ~~~ 启动 ~~~ rinetd ~~~ 我这边设置9503端口转发到ssh的22 # mac设置开启ssh端口 系统设置中共享 远程登录打钩,选所有人 ![](https://box.kancloud.cn/9b22ba7fb03367fb7e59011e4f201fa7_1256x724.png) # ssh指定端口 ~~~ ssh 到指定端口 ssh -p xx user@ip xx 为 端口号 user为用户名 ip为要登陆的ip ~~~ # shell 要有curl,里面查公网ip用的是一个url ~~~ #!/bin/sh #By h46incon #Dependences: bind-dig, curl, openssl-util, tr, sort ## ----- Setting ----- AccessKeyId="testid" AccessKeySec="testsecret" DomainRecordId="00000" # DomainRR, use "@" to set top level domain DomainRR="www" DomainName="example.com" DomainType="A" # DNS Server for check current IP of the record # Perferred setting is your domain name service provider # Leave it blank if using the default DNS Server DNSServer="dns9.hichina.com" # The server address of ALi API ALiServerAddr="alidns.aliyuncs.com" # A url provided by a third-party to echo the public IP of host MyIPEchoUrl="http://members.3322.org/dyndns/getip" # MyIPEchoUrl="http://icanhazip.com" # the generatation a random number can be modified here #((rand_num=${RANDOM} * ${RANDOM} * ${RANDOM})) rand_num=$(openssl rand -hex 16) ## ----- Log level ----- _DEBUG_=true _LOG_=true _ERR_=true ## ===== private ===== ## ----- global var ----- # g_pkey_$i # param keys # g_pval_$key # param values g_pn=0 # number of params _func_ret="" ## ----- Base Util ----- _debug() { ${_DEBUG_} && echo "> $*"; } _log() { ${_LOG_} && echo "* $*"; } _err() { ${_ERR_} && echo "! $*"; } reset_func_ret() { _func_ret="" } ## ----- params ----- # @Param1: Key # @Param2: Value put_param() { eval g_pkey_${g_pn}=$1 eval g_pval_$1=$2 g_pn=$((g_pn + 1)) } # This function will init all public params EXCLUDE "Signature" put_params_public() { put_param "Format" "JSON" put_param "Version" "2015-01-09" put_param "AccessKeyId" "${AccessKeyId}" put_param "SignatureMethod" "HMAC-SHA1" put_param "SignatureVersion" "1.0" # time stamp local time_utc=$(date -u +"%Y-%m-%dT%H:%M:%SZ") _debug time_stamp: ${time_utc} put_param "Timestamp" "${time_utc}" # random number _debug rand_num: ${rand_num} put_param "SignatureNonce" "${rand_num}" } # @Param1: New IP address put_params_UpdateDomainRecord() { put_param "Action" "UpdateDomainRecord" put_param "RR" "${DomainRR}" put_param "RecordId" "${DomainRecordId}" put_param "Type" "${DomainType}" put_param "Value" "${1}" } put_params_DescribeDomainRecords() { put_param "Action" "DescribeDomainRecords" put_param "DomainName" ${DomainName} } pack_params() { reset_func_ret local ret="" local key key_enc val val_enc local i=0 while [ $i -lt ${g_pn} ] do eval key="\$g_pkey_${i}" eval val="\$g_pval_${key}" rawurl_encode "${key}" key_enc=${_func_ret} rawurl_encode "${val}" val_enc=${_func_ret} ret="${ret}${key_enc}=${val_enc}&" i=$((++i)) done #delete last "&" _func_ret=${ret%"&"} } # ----- Other utils ----- get_my_ip() { reset_func_ret local my_ip=$(curl ${MyIPEchoUrl} --silent --connect-timeout 10) #echo ${my_ip} _func_ret=${my_ip} } get_domain_ip() { reset_func_ret local full_domain="" if [ -z "${DomainRR}" ] || [ "${DomainRR}" == "@" ]; then full_domain=${DomainName} else full_domain=${DomainRR}.${DomainName} fi local ns_param="" if [ -z "${DNSServer}" ] ; then ns_param="" else ns_param="@${DNSServer}" fi _func_ret=$(dig "$ns_param" "${full_domain}" +short) } # @Param1: Raw url to be encoded rawurl_encode() { reset_func_ret local string="${1}" local strlen=${#string} local encoded="" local pos c o pos=0 while [ ${pos} -lt ${strlen} ] do c=${string:$pos:1} case "$c" in [-_.~a-zA-Z0-9] ) o="${c}" ;; * ) o=$(printf "%%%02X" "'$c") esac encoded="${encoded}${o}" pos=$(($pos + 1)) done _func_ret="${encoded}" } calc_signature() { reset_func_ret local sorted_key=$( i=0 while [ $i -lt ${g_pn} ] do eval key="\$g_pkey_$i" echo "${key}" i=$((++i)) done | LC_COLLATE=C sort ) local query_str="" for key in ${sorted_key} do eval val="\$g_pval_${key}" rawurl_encode "${key}" key_enc=${_func_ret} rawurl_encode "${val}" val_enc=${_func_ret} query_str="${query_str}${key_enc}=${val_enc}&" done query_str=${query_str%'&'} _debug Query String: ${query_str} # encode rawurl_encode "${query_str}" local encoded_str=${_func_ret} local str_to_signed="GET&%2F&"${encoded_str} _debug String to Signed: ${str_to_signed} local key_sign="${AccessKeySec}&" _func_ret=$(/bin/echo -n ${str_to_signed} | openssl dgst -binary -sha1 -hmac ${key_sign} | openssl enc -base64) } send_request() { # put signature calc_signature local signature=${_func_ret} put_param "Signature" "${signature}" # pack all params pack_params local packed_params=${_func_ret} local req_url="${ALiServerAddr}/?${packed_params}" _debug Request addr: ${req_url} local respond=$(curl -3 ${req_url} --silent --connect-timeout 10 -w "HttpCode:%{http_code}") echo ${respond} } describe_record() { put_params_public put_params_DescribeDomainRecords send_request } update_record() { # get ip get_my_ip local my_ip=${_func_ret} # Check if need update _debug My IP: ${my_ip} if [ -z "${my_ip}" ]; then _err Could not get my ip, exitting... exit fi get_domain_ip local domain_ip=${_func_ret} _debug Current Domain IP: ${domain_ip} if [ "${my_ip}" == "${domain_ip}" ]; then _log Need not to update, current IP: ${my_ip} exit fi # init params put_params_public put_params_UpdateDomainRecord ${my_ip} send_request } main() { describe_record #update_record } main ~~~ # 判断主机是否支持 ### **进入BIOS** 当电脑开机启动时,通过反复按键盘“DELETE”键或“F2”键,进入到主板BIOS设置界面。更多启动主板BIOS设置界面帮助,参考[百度经验](http://jingyan.baidu.com/article/b24f6c82c11ad286bfe5da23.html)。 ### **开启唤醒功能** 通常到“Power Managment(电源管理)”下寻找如下列选项: "Boot on LAN"; "Wake on LAN"; "PME Event WakeUp",; "Resume by MAC LAN"; "Wake-Up by PCI card"; "Wake Up On PCI PME"; "Power On by PCI Card"; "WakeUp by PME of PCI"; "Power On By PCI Devices"; "WakeUp by Onborad LAN"; "Resume By PCI or PCI-E Ddevice"或类似的东西,并可以启用它。 可视图形化的UEFI BIOS,可参考下列方式设置: 高级 > 高级电源管理(APM)> 开启**Resume By PCI or PCI-E Ddevice**(由pci/pcie设备唤醒)选项 **联想主板** 进入**Power——Automatic Power ON**——**Wake On LAN**设为**Enabled** ![](https://box.kancloud.cn/896e2ea9ea8f22de665855d7900bc461_537x447.png) **华硕主板** 进入高级——高级电源管理——开启由PCI/PCIE设备唤醒选项 ![](https://box.kancloud.cn/6b3b53c2eb759ef48b8ba8daafdf0f73_549x472.png) **技嘉** 进入BIOS功能——网络启动——选择Legacy First或UEFI First选项 ![](https://box.kancloud.cn/f8ede3afa860835d275d549f0215b106_492x373.png) ## 关闭节电功能 远程开机需要网卡保持待机,关机后网卡灯不亮,请检查主板是否开启节能模式。因各厂商对此功能名称定义不一,常见的节电功能选项: 1. 假如有**Low Power Mode**选项,一定要设置为**Off** ![](https://box.kancloud.cn/f901d67130170a8bd2e4b2b99d5a7ed7_638x373.png) 2. 或者是**ErP**和**EuP**选项,设置为**Disabled** ![](https://box.kancloud.cn/dd604a1f3a4615308b18ab318b16920d_646x145.png) # 断电后自动开机 wakeonlan怕非正常关机, 如果非正常关机, wakeonlan会失效, 用这个代替wakeonlan失效 ![](https://img.kancloud.cn/d0/7d/d07d3d825991d0b5ad446db0e29a5fd8_1124x504.png) # linux系统设置唤醒 检查网卡是否支持唤醒功能,输入命令**ethtool eth0**打印出网卡的信息 ![](https://box.kancloud.cn/e5f422377f7c21c9b02c6c2b089d8954_595x394.png) Supports Wake-on 值为g,表示网卡支持远程开机;若为d,则不支持。 Wake-on值为g,表示网卡已开启远程唤醒功能; 若为d,则输入命令 ethtool -s eth0 wol g 开启。 命令执行后,输入ethtool eth0,检测是否成功开启wake on lan功能