在旧金山办理巴西签证

在旧金山办理巴西签证需要准备的材料如下

  • USPS money order $115 收件人写 Consulate General of Brazil
  • 2 inch x 2 inch 白底免冠照片一张
  • 驾照复印件
  • 美国有效身份证明,比如绿卡
  • 机票订单
  • 打印的在线申请表确认信

需要注意的是money order必需是USPS开局的。Safeway/Walmart的不行。

申请签证前需要在线填写申请表,网址在 https://formulario-mre.serpro.gov.br/sci/pages/web/pacomPasesWeb.jsf?aba=-6

这个网站的问题在于偶尔英文翻译里还会夹杂葡萄牙文,请备好翻译软件。填表的过程中也会让上传照片电子版和机票行程电子版,请一并准备。最后填写完成提交后会有一个带编号的确认页面需要打印并签字。

巴西驻旧金山领馆面签不需要提前预约,到了领号即可。需要注意的是签证服务仅在早9点到11点之间提供。停车的话最精生的选择是附近的St. Mary’s Square Parking Garage – Lot #49, Kearny Street, San Francisco, CA

巴西领馆网站说明是5个工作日下签证,但我面试的时候让我差不多7个工作后再去领。签证上的issue date是在5天内,也许只是工作人员为了留下足够的余量。

最后收到的签证是5年多次有效,每次停留不超过90天。

Keepalived实现廉价HA

最近在dockerize各种home lab上的服务,其中遇到的一个问题就是如何实现HA。最方便的实现方式是打开eBay.com搜索F5 Big IP 购买硬件Load Balancer。最廉价的方式是多个设备间跑VRRP协议实现自动Fail over切换。Keepalived 就是一个精细生活VRRP的软件实现。

具体用例为两台Docker node上各跑了一个container运行unbound提供recursive DNS服务。任意一台机器下线(不管是container下线或是node下线)都由另一台机器在同一个IP地址下继续提供服务。切换期间网络不不会中断。

既然已经有了两台运转正常的Docker node,显然Keepalived跑在Container里是最经济且便于管理的。这里用到的docker image是 https://github.com/osixia/docker-keepalived

需要注意的是两台机器的sysctl需要设置 net.ipv4.ip_nonlocal_bind=1 在Ubuntu上可以通过修改 /etc/sysctl.conf 并运行 sysctl -p /etc/sysctl.conf 实现。在RancherOS上需要修改cloud-config.yml 具体参考官方文档

并且这两个container需要跑在host network上且赋予 CAP_NET_ADMIN (--cap-add NET_ADMIN

以下是用docker-composer 和直接运行docker run的两种配置。

# docker-composer.yml

keepalived:
     container_name: keepalived
     image: arcts/keepalived:latest
     environment:
       - KEEPALIVED_AUTOCONF=true
       - KEEPALIVED_STATE=MASTER
       - KEEPALIVED_INTERFACE=eth0
       - KEEPALIVED_VIRTUAL_ROUTER_ID=2
       - KEEPALIVED_UNICAST_SRC_IP=10.2.1.10
       - KEEPALIVED_UNICAST_PEER_0=10.2.1.11
       - KEEPALIVED_TRACK_INTERFACE_1=eth0
       - KEEPALIVED_VIRTUAL_IPADDRESS_1="10.2.1.12/24 dev eth0"
     network_mode: "host"
     cap_add:
       - NET_ADMIN
# docker run command
docker run -d --name keepalived --net=host --cap-add NET_ADMIN \
-e KEEPALIVED_AUTOCONF=true               	\
-e KEEPALIVED_STATE=BACKUP           		\
-e KEEPALIVED_INTERFACE=eth0                \
-e KEEPALIVED_VIRTUAL_ROUTER_ID=2           \
-e KEEPALIVED_UNICAST_SRC_IP=10.2.1.11    	\
-e KEEPALIVED_UNICAST_PEER_0=10.2.1.10     \
-e KEEPALIVED_TRACK_INTERFACE_1=eth0        \
-e KEEPALIVED_VIRTUAL_IPADDRESS_1="10.2.1.12/24 dev eth0" \
arcts/keepalived

至此 IP地址 10.2.1.12 就由 10.2.1.10 为master ,10.2.1.10下线 则10.2.1.11 自动由backup转为master继续提供服务

在Cisco路由器上使用Let’s encrypt 证书

以下是一个笔记,用来更新Cisco 28xx系列路由器上的Anyconnect 证书

1. 生成Let’s encrypt 证书。我习惯用getssl

2. 加密private key 这台设备较老,只接受des加密的格式
openssl rsa -des -in privkey.pem -out privkey-enc.pem
这时候会要求输入一个密码,在下文会用到

3. 从private key中提取public key
openssl pkey -in privkey.pem -pubout -out pubkey.pem

4. 登陆到路由器并切换到配置模式

enable
configure terminal

5. 创建ISRG Root certificate trustpoint

crypto pki trustpoint ISRG_Root_X1
chain-validation stop
revocation-check none
enrollment terminal pem
exit

6. 导入ISRG Root certificate (从 https://letsencrypt.org/certs/ 下载)
crypto pki authenticate ISRG_Root_X1
粘帖复制证书后回车在新的一行键入quit

7. 创建中间证书 Let’s Encrypt Authority X3 (Signed by ISRG Root X1) 的trustpoint

crypto pki trustpoint Lets_Encrypt_Authority_X3_signed_by_ISRG_Root_X1
chain-validation continue ISRG_Root_X1
revocation-check none
enrollment terminal pem
exit

8. 同样粘帖复制中间证书 (从 https://letsencrypt.org/certs/ 下载)
crypto pki authenticate Lets_Encrypt_Authority_X3_signed_by_ISRG_Root_X1
粘帖复制证书后回车在新的一行键入quit

9. 导入路由器证书
crypto pki import host.domain.com-cert pem terminal @Password@
这里的@Password@ 替换为 #2 中自定义的密码
粘帖复制 Let’s Encrypt Authority X3 的中级证书,也就是在#8 中用过的。在换行后输入quit
粘帖复制 privkey-enc.pem 中的内容,注意不要有空行。在换行后输入quit
最后粘帖复制 #1 中创建的证书。在换行后输入quit
如果一切正常的话应该能看到
"% PEM files import succeeded."

10. 替换原有的证书
这里用到的gateway名字是我本机的,请根据实际情况输入

webvpn gateway gateway_1
ssl trustpoint host.domain.com-cert

90天过期前需要重新更新服务器证书并且重复 #10 步

参考文献
Tutorial: Get Let’s Encrypt on Cisco routers/switches

隐没在闹市中的珍宝 Granville Island

第一次去温哥华前就有朋友推荐过Granville Island上的Fish market。之后多次入境都与之擦肩而过,真正踏足这个小岛还是第一次。这还要归功于在Burrard Bridge下的一瞥。

在游船的尽头有几个大字招牌就是Granville Island Public Market。一开始以为从这个码头就可以步行抵达,绕了一圈才发现只有坐船或是开车绕道才能进去。这座岛三面环水,原本是两座沙洲,于1915年被填成35英亩的工业用地,随着经济大萧条一度沦为贫民窟直到二战期间再度投入大量生产。现在已经是温哥华著名旅游景点之一。

工业的痕迹依然可见,只不过加上了一丝艺术气息。

因为是工作日的关系岛上的停车并不困难,多个收费停车场都有空位根据车牌买停车票即可。岛上最著名的就是这个Public Market。

一开始以为只是一个Fish market或Farmer’s market,进去后才发现里面堪称一个宝库。

首先看到的就是各色水果蔬菜,五彩斑斓的摆放配合灯光映射让人垂涎欲滴。

有一个日本人开的鱼铺(也就是朋友推荐过的)有卖新鲜生蚝,如果有带上一把开蚝刀不妨买一瓶Tabasco调料带回住处慢慢品尝。看到这些虾米蟹腿肉此刻我只想吃一顿火锅。

往里走有一家巨大的茶店,可以买茶叶回去也可以现点一杯热茶当场冲泡。店主看上去是日裔,还会讲日语招待客人。

茶店的斜对角是一家马卡龙专营。第一次看到如此多品种花色的马卡龙在一个柜台展示。可以单买也可以选择6只,12只装(听上去有点熟悉?)

店的一角甚至还有一个马卡龙搭建的Eiffel Tower 不知道是不是属于非卖品

店招在此,看着这块招牌就找到了

迷你马卡龙金字塔,不知道这样一罐下去血糖会升多高。

市场另一角不乏各色面包三明治咖啡店,逛累了也可以坐下喝一杯再走。门外有不少供人歇腿的长凳。今年的枫树红得比往年更晚一些。可以点一杯热巧克力坐在门口看一天的鸽子,暂时忘却工作带来的烦恼。

在旧金山领事馆办理日本多次往返签证

根据日本外务省今年5/1开始的新政策,在海外的中国护照持有人满足条件的也可以办理日本国多次往返签证。鉴于日本领事馆在美国是分区管辖并且各自为政,具体每个领馆的要求各有不同。以下仅限于今年6月在旧金山领事馆办理的经验,并不具备普遍性。

官方网站关于中国护照申请多次往返签证的连接 http://www.sf.us.emb-japan.go.jp/itpr_en/e_m02_01_10.html

实际办理中收取了如下材料

  1. 护照原件 以及 4.5×4.5 方形照片一张
  2. 有效身份证明(有绿卡的需要提供复印件,并且它们会在检查原件后在复印件上盖验讫章;H1b需要提供I797原件和复印件以及I-94,持有EAD卡的需要提供EAD卡原件复印件)
  3. 三个月内的往返机票和酒店订单。一定要三个月内,否则会让你推迟到临行前三个月再来办理签证。
  4. 行程单一份,需要说明每一天去哪里做什么,并且当天住宿何处,联系方式
  5. 六个月银行账单。要求必须是连续六个月
  6. 最近两张paystub
  7. 签证申请表格(领馆网站有下载电子版)需要中文姓名以及身份证号
  8. 陈述信,说明为什么需要多次往返签证 (可以参照这个链接里的模版  http://dailynews.sina.com/gb/wapnews/discover/usa/20170530/144020114.html )

其中需要三个月内的机票酒店订单,以及六个月连续银行账单属于旧金山领馆特色要求。在收件后给的回执上可以看出准备给你S(单次)或M(多次)往返签证,价格分别是单次$27,多次$55。收现金不收信用卡或个人支票,取件时支付。一般3个工作日即可取件。

根据身边的经验,旧金山领馆签发的多次往返均为5年有效,每次不超过90天版本。洛杉矶领事馆有签发3年有效,每次不超过30天版本。YMMV

Android下设置国产流氓软件权限静默

同一个软件在iOS平台有的话首选iOS,权限控制更严格且程序无法作出反抗。如果遇到因为地区限制(比如某国产流媒体音乐服务软件仅限在中国市场下载)只能在Android上安装的话就需要手工设置部分权限静默。

以下内容参考了这篇文章

首先需要安装adb。MacOS下可以用homebrew
brew install android-platform-tools

开启手机usb debugging (Settings -> About phone -> Build number连续点击10次开启developer mode)
连接上手机后首先查找一下安装的软件包名。
在这个例子中用的虾米音乐
adb shell pm list packages|grep -i xiami
package:fm.xiami.main

得到结果是fm.xiami.main

之后用appops把某些权限设置为ignore。不能设置成deny因为程序在检测到没有获得该项权限时会拒绝服务(所以我们叫他流氓软件)设置成ignore的话程序无法detect到这个变化。不过第一次启动程序还是不得不授予所需的权限否则程序拒绝启动,这一点不知道是否将来有workaround。


adb shell appops set fm.xiami.main WRITE_SMS ignore
adb shell appops set fm.xiami.main OP_READ_PHONE_STATE ignore

这两个权限一个是发送短信另一个是读取电话信息权限。一个音乐软件要求电话管理以及发送SMS权限实属过分。

检查该软件获得的所有权限

$adb shell appops get fm.xiami.main
COARSE_LOCATION: ignore
FINE_LOCATION: allow; time=+21m35s704ms ago; rejectTime=+12m39s614ms ago
POST_NOTIFICATION: allow; time=+14m32s602ms ago
CALL_PHONE: ignore
WRITE_SMS: ignore; rejectTime=+15m8s617ms ago
WRITE_SETTINGS: default; rejectTime=+15m15s701ms ago
READ_CLIPBOARD: allow; time=+12m35s36ms ago
WRITE_CLIPBOARD: allow; time=+12m35s34ms ago
TAKE_AUDIO_FOCUS: allow; time=+18m42s431ms ago
TOAST_WINDOW: allow; time=+14m30s54ms ago; duration=+2s527ms
OP_READ_PHONE_STATE: ignore; rejectTime=+13m13s115ms ago
READ_EXTERNAL_STORAGE: allow; time=+15m7s9ms ago
WRITE_EXTERNAL_STORAGE: allow; time=+15m7s9ms ago
RUN_IN_BACKGROUND: allow; time=+3m11s711ms ago

其中FINE_LOCATION 设置ignore但不知出于何种原因无法生效。此外在权限后没有出现time的即意味着程序没有请求该项权限(我事先禁止了CALL_PHONE) 对于FINE_LOCATION,据 @yegle建议可以通过禁止RUN_IN_BACKGROUND 权限来达到程序关闭即无法探知用户位置实现。

Cisco 7941G IP Phone 刷SIP固件

托@lty1993 的福,最近入手了几台便宜的Cisco 7941G IP Phone,由此开启了刷机之旅。

默认情况下这部电话通过Cisco自家的Call manager系统来provison和管理。仅在固件升级到9.2 SIP之后才能连接标准的SIP服务器当作一部SIP Phone来独立使用。Cisco的各种文档里只描述了如何通过自家系统provison,对于如何通过TFP刷机之有寥寥数语。@lty1993 反复试验探索出了如下刷机方法,我在此做一份笔记,希望可以帮到(想淘便宜电话的)后人

首先要确定你的电脑固件版本,低于8.0的情况下没法直接升级。建议先做一个hard reset后从8.0固件刷起。方法是按住#键接电源,看到液晶屏右边选择两路线路的灯(以下简称两灯)黄色闪烁后放开,按3491672850*# 后机器下方耳机,静音,speaker(以下简称三灯)开始红色闪烁即开始了删除固件的过程。这个过程完成后电话开机液晶屏是完全不现实内容的,只有两灯交替闪烁绿色。

这个时候就要开始刷机。你需要一台TFT服务器根目录下放置电话固件内容(稍后会详细解释)。并且你的DHCP服务器需要添加一个额外的Option。code为150,value是转成16进制的TFTP server的IP地址。比如你的IP如果是192.168.66.3,那value就是0xC0A84203 注意前面的0x不能省略。这样做的目的是为了让电话在启动的时候通过DHCP拿到TFTP服务器地址从而进行固件升级。

根据无数次人肉实验得出的经验是固件升级可以跳级,但是必须遵循 8.0 (3)-> 8.5(2) -> 9.4(2) -> 9.2(2)[sip] 这个顺序。低于8.0的固件需要先做hard reset后才能刷入8.0固件。固件可以从Cisco网站下载。记得需要下载zip文件版本,文件解压缩后得到的文件放入TFTP服务器根目录。在Linux下我们尝试过tftp-hpa,在Mac OSX下有TftpServer都测试可以正常使用。

紧接着刚才提到的hard reset后两灯闪烁绿色情况。如果这个时候TFTP server开启并且DHCP option设置成功的话,你的电话应该能自动开始刷机。刚刚hard reset后升级液晶屏是没有显示的,但是电话右下角的三灯会慢慢地出现一个红色灯从左往右移动,这个过程会持续一分半钟。如果发现红色快速一闪而过那说明固件校验不合格或版本非法。

当升级8.0 成功后第一次启动就能看到液晶屏上又出现久违的Cisco字样。这时候可以准备更新TFTP上的固件并且拔掉电话电源。之后还是需要按着#键开机,并且在两灯黄色闪烁的时候soft reset,按键如下 123456789*0# 这个时候电话会立刻重启并且寻找TFTP服务器开始升级。在固件升级的同时可以在液晶屏上看到正在更新的文件和进度显示。

前三次升级 8.0, 8.5, 9.4的时候都只需要固件文件即可,最后一次升级9.4 SIP完成后开机会自动在TFTP服务器上寻找SIP服务器配置和dial plan配置文件。这个时候情确保TFTP server继续开启。这两个配置文件也是Cisco文档里找不到具体schema,全靠 @lty1993 人肉一点点摸索出来。其中SEPXXXXXXXXXXXX.cnf.xml 中的XXXXXXXXXXXX需要替换为电话的Mac地址其中字母全部大写。dialplan-XXXXXXXXXXXX.xml 文件名是在SEPXXXXXXXXXXXX.cnf.xml中指定的, 所以不一定需要叫这个名字,这里仅仅为了便于管理才保持同样命名规则。

下面是2个配置例子。基本上修改下服务器地址和extension/password就可以正常使用了。需要注意的是这部电话似乎只支持SIP TCP链接,而freepbx/asterisk默认是UDP,需要手工开启TCP支持,否则registering会一直注册不上。 <transportLayerProtocol>这个参数值为1即为TCP,2为UDP,默认是4(不知道是什么?也许是CM中某个协议?)

需要修改的地方还有EXTENSION_NUMBER 换成SIP服务器上真实的extension号码,比如100. <authPassword> 的值替换成账户密码。<dialTemplate> 的值替换为你的dial plan文件用户名。

至此当你的电话升级固件至9.2 SIP之后开机能读到正确的2个配置文件就应该能立刻注册上你的SIP服务。如果发现registering一直不过,首先检查你的服务器是否支持TCP连接。

Cisco网站固件下载地址
用户配置文件

配置文件修改还可以参考 这个网址

如果你在配置文件中发掘中了新功能不妨留言和大家分享一下,比如通讯录功能如果可以和LDAP连起来应该会很有意思。

加州买枪记 [一]

本文仅代表本人意见,不可视为对California Gun Law的解释。

省略一万字关于究竟该禁枪还是拥枪的讨论。我本人对于枪的态度请参考这篇文章《华人为什么应该拥枪》

即使在深蓝色的加州,作为一名持H1B签证的外星人 (Resident Alien)只要满足一定条件一样可以享受civil right赋予的合法拥有枪支的权利。这个条件之一就是拥有一张有效的California Hunting License。

Hunting License是在拥有了hunting certificate之后付费在Sports Authority或者Walmart购买。该许可需要annually renew。为了获得一张hunting certificate有两种方式

  1. 参加10小时的课程,通过100道题的written test和枪支操作示范practical test就可以拿到。100道题主要是选择题,混有若干道填空
  2. 参加网上的课程 http://www.hunter-ed.com/ 并通过在线考试。之后参加一个4小时的follow up course(需要线下参与),并且通过和第一条一样的100道笔试题以及操作考试后获得

课程安排在Department of Fish and Wildlife 网站有查询,http://www.dfg.ca.gov/huntered/classes.aspx 需要分清10小时课程和4小时课程是2个不同连接,不要搞混了。

这100道题需要达到80%通过才能被授予hunting certificate。课程本身涵盖了枪支介绍,枪支安全,弓箭使用,狩猎知识,野外生存等篇幅,内容还是挺有意思的。值得花点心思认真学习。

在持有hunting license之后就可以去枪店购买长枪了(rifle,shortgun)如果要购买手枪则需要持有一个handgun safety certificate,这个在任何一个枪店都会有考试。这个手枪证(HSC)是绿卡和公民在购买手枪前也需要考的。一共30道选择题,75%正确就能过,任何一个智力正常的人都可以在阅读30分钟到1个小时的safety guide之后以100%正确率通过。(如果你fail的话请pm我你常去的靶场,我一定尽量避免和你同时出现在那个地方)

还有一个需要注意的地方就是年龄限制,满18岁可以购买长枪,但是手枪需要年满21岁才可以购买。加州对于手枪有一个30天内只能购买一把手枪的限制,长枪不受限。同时加州还有一个非常有地方特色的“合法”手枪roster,只能购买roster上的手枪。如果你想买一把off list的枪,那就只能求助于SSE (single shot exemption),简单地说就是在经过授权的枪店帮你改装成符合加州标准的手枪并且满足一次击发只能发射一次的条件之后就可以合法卖给你,这个过程当然要收取若干“保护费”。托政客的福,这个SSE在2015年1月1日后就彻底被Ban了,如果想买off list的手枪,赶在年底前趁早吧。当然,改装的是枪的本身结构,对于弹夹,加州不允许持有超过10发的“大容量”弹夹。所以不管长枪短枪最多只能有10发弹夹。

当你兴高采烈地在枪店挑了枪之后还不能立刻把枪带走,加州政府规定,需要额外10天时间来让DOJ (Department of Justice)来对你做一个background check以确保你没有犯罪记录,没有精神问题,没有若干其他受法律限制无法合法持有枪支的种种问题。你每一次购枪需要等这10天。(注1:今天听到消息说如果你在COE certificate of eligibility list 上的话从第二次购枪开始可以不需要这10天等待。消息有待确认)

关于这个购买手枪需要间隔30天的限制仅限于你从dealer那里买枪,如果是私人间交易(private party sale)的话不受这个限制。但是切记私人交易也需要到FFL (federal firearm license) 执照持有人那里去登记,不能一手交钱一手交货,否则以后下家犯了事就记你头上了。

至于长枪我还没有太多研究,暂时说不上具体有什么限制。待以后更新吧。至于购买子弹可以在网上买了直接送货到门,部分城市比如San Francisco,Oakland不允许送货上门(San Jose目前还没有这个问题),有些dealer为了省事就直接不用加州地址。

买枪愉快,注意安全。

在家搞了IPv6 tunnel

几个月前就在Comcast IPv6 trials报名申请IPv6线路测试,等了几个月收到的唯一更新就是测试名额已满,什么时候再开不知道。对Comcast不抱什么希望,还是搞个HE的IPv6 tunnel接入。Router上跑的Tomato USB v1.28支持IPv6 6in4 static tunnel。

首先就是在Hurricane Electric申请一条Regular Tunnel。我选择了离家物理距离最近的Fremont机房。申请完成后会看到一堆参数,在Router上设置如下。

Assigned/Routed Prefix 填Routed IPv6 Prefixes – Routed /64中的内容

Tunnel Remote Endpoint (IPv4 Address)填Server IPv4 Address中的IPv4地址,也就是在创建Tunnel的时候你选择的对应机房IPv4地址

Router IPv6 Address 对应Server IPv6 Address

Tunnel Client IPv6 Address对应Client IPv6 Address

Router上保存后你可以在终端上获取到IPv6地址,然后自然是到  这里测试下你的IPv6 tunnel是否联通。如果一切正常的话,恭喜你,你可以看到KAME那只乌龟的动画了。

如果你的ISP没有给你提供static ipv4的话,你每次获得新IP还需要更新下tunnel broker那边你的ip地址。在Tunnel Details里的Advanced tab有具体说明。

补充下,如果是动态IP地址,那么需要设置一个DDNS来周期性地向HE更新你的client IPv4地址。Basic -> DDNS 里service可选het.net IPv6 tunnel broker,所以即使你没有固定IP也可以方便使用HE的IPv6 tunnel

解决 svn: local missing, incoming edit upon merge

事情源于今天下午做的一个svn rebase操作

trunk上有文件a.sql, 在newbranch上被改名成了b.sql。在我对newbranch做rebase之前,trunk上的a.sql又从其他branch merge到了一些改动,于是当我svn merge trunk -> newbranch的时候就不可避免的出现了tree conflict。这个时候用svn st查看newbranch上working copy的状态就会发现这个文件的状态是 “> local missing, incoming edit upon merge”。

解决办法就是首先svn resolve --accept working a.sql,将tree conflict先解决,这时候在working copy里a.sql是不存在的(因为working copy里只有b.sql)。然后需要将a.sql从其他branch merge来的改动也merge回newbranch上的b.sql。

svn log --stop-on-copy newbranch 获取newbranch创建时的revision,假设为r100
svn merge -r100:HEAD '^/trunk/a.sql' b.sql 把所有从r100开始到head所有对于a.sql的改动全部merge到b.sql。至此,这个头疼的local missing, incoming edit upon merge就解决。如果有多个文件则依次逐个merge。

归根结底这源于svn对于文件移动的实现是copy + delete,这样会赋予改名后的新文件一个新的revision。2002年的时候就有人因此开了一个bug ticket,不过看样子是不会有fix了…

如果想一劳永逸解决这个问题,最终解决方案就是放弃svn转投git