azure 羊毛(二)

azure 学生包除了那一个 Linux 服务器,还有以下的东西(参考Azure 学生订阅包含内容 - 简书

一年时间内包括:

100美元额度

2个免费主机(b1s 1核1G)
1个windows主机
1个linux主机

2个64G的免费磁盘

一个250G的SQLSERVER数据库

一个5 GB Azure Cosmos DB (可当做mongodb用)

每月20G流出流量免费(流入流量全免)

10个免费的App Service(可用于搭建OneIndex等不太占用流量的站点,好处有自带https,自带伪静态支持,自带用户验证,可以设成只有自己和指定的微软账号才能访问网站,并且全鼠标可视化操作,无需命令行敲代码。)

20G 这个存疑(我之前得到的消息是 15G)。两个数据库没想通有啥用。。。那剩下的羊毛,就是 windows server 和 app service 这俩玩意了。

Windows server

创建

参考文章:Windows Azure学生订阅额度完全使用(薅干)指南教程 - 教程资源|网络资源 - 如有乐享

参考文章说的很清楚了,总结起来就是:

  1. 建的时候选 b1s smalldisk windows server 2012 r2,不用 smalldisk 后续磁盘缩不到 64g;单核也不建议用更高配置的系统;
  2. 创建成功后停止虚拟机,修改磁盘大小。

另外还有两个细节:

  1. 关闭实例优惠(默认应该就是关着的,而且一般人账号里面真的会有 windows server 2012 的授权吗)
  2. 用新的资源组,和之前 Linux 那个资源组区分开,以免删除的时候出现不必要的麻烦。

接着就能通过 rdp 愉快的使用了。一般来说,windows server 我们是用来挂机的,不过。。。如果我也想用这玩意来做「科学」用途呢(

证书申请与验证

Windows 的各种操作大部分人都很熟悉,但搭建像 Linux 那样用途的服务器,因为环境和生态的原因,操作上还是有巨大的差距的。Windows 这边申请证书虽然有比较官方的 win-acme,但一个是刚转过来的我对这玩意比较陌生,二个是它用的 cloudflare 接口不仅是外挂的而且还要单开 api 接口参数, 而 Linux 这边的 acme.sh 只需要默认的 CF_Key,这么一对比还是后者更趁手。Windows 上用熟悉的 Linux 工具解决问题,呃。。。这很不优雅但有用(x)

  1. 装 chocolatey 和 git。

    吐槽一句自带的服务器版 ie 实在是太烦人了。。。还好有 chocolatey 可以直接装东西不用通过浏览器(

    装 git 的原因是因为 git 自带精简版的 mingw。当然如果你要运行的东西需要一些其他的 dependence,装 cygwin 或 msys2 也不是不行(

    1
    2
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
    choco install git -y
  2. 用 choco 安装 acme.sh。

    1
    choco install acme-sh -y

    导航到 acme.sh 的安装目录,目前最新的版本是 2.88,用 chocolatey 安装的话大概就会在 C:\ProgramData\chocolatey\lib\acme-sh\tools\acme.sh-2.8.8 这里。

    右键空白处,点击 git bash here

  3. 接下来就是大家熟悉的操作了。可以参考一步到位的vps从入门到放弃 | Bao’s 备忘录。最后证书建议安装在一个路径固定的目录(方便以后操作,放在桌面等 C:/Users/xxx 打头的目录),但不要放在 c 盘根(权限问题)。我自己放在 %public% 文件夹(即 C:\Users\Public),新建的 ssl 文件夹中。

    1
    2
    3
    4
    5
    export CF_Key="xxxxxx"
    export CF_Email="xxxxxx"
    ./acme.sh --issue --dns dns_cf -d baobaobao.xxx -d *.baobaobao.xxx -k ec-256
    mkdir C:\\Users\\Public\\ssl
    ./acme.sh --installcert -d baobaobao.xxx --keypath 'C:\Users\Public\ssl\baobaobao.key' --fullchainpath 'C:\Users\Public\ssl\baobaobao.crt' --ecc
  4. acme.sh 的自动续签依赖于 Linux 的 crontab。windows 没这玩意,只能自己搞个伪劣版(

    新建 acme-cron.sh 放在 %public% 下

    1
    2
    3
    4
    #!/usr/bin/env bash
    cd 'C:\ProgramData\chocolatey\lib\acme-sh\tools\acme.sh-2.8.8'
    ./acme.sh --renew --dns dns_cf -d baobaobao.xxx -d '*.baobaobao.xxx' -k ec-256 --ecc
    ./acme.sh --installcert -d baobaobao.xxx --keypath 'C:\Users\Public\ssl\baobaobao.key' --fullchainpath 'C:\Users\Public\ssl\baobaobao.crt' --ecc

    在同一目录下新建 acme.bat

    1
    2
    @echo off
    cmd /c ""%PROGRAMFILES%\Git\bin\bash.exe" --login -i -- %PUBLIC%\acme-cron.sh"

    新建一个计划任务

    1
    schtasks /Create /tn acme-renew /tr "%public%/acme.bat" /sc  DAILY /st  00:00:00

    每天 0 点这个脚本就会弹窗定时续签了。反正是远程 rdp,又不是 24 小时盯着的,弹窗啥的,无所谓吧~


什么你说其他内容?不就剩下一个工具吗。

工具选择 v2,因为 v2 客户端服务端二进制是二合一的,只取决于配置文件如何配置,不需要再去考虑自己二进制版本是 sever 版还是 client 版。还有记得开放 web 面板 + 系统内防火墙,开放入站端口即可。如果考虑 fullcone 的话,相应端口 + 高位端口都要打开,,否则仅开放对应端口就行。系统内可以直接敲命令放行对应应用,参考下面这个命令:

1
New-NetFirewallRule -DisplayName "xray" -Enabled True -Program "C:\Users\Public\v2rayN\xray.exe" -Description "xray" -Group "xray" -Action Allow -Protocol ANY

还不会就手放键盘脑补吧,前有嘴含内存条脑补游戏画面,今有申请了证书后手放键盘脑补 p 站首页(雾

更换 rdp 端口(21.3.16 更新)

鼓捣了一下 rdp 登录 bot 的事情,结果查日志的时候发现好家伙一堆上来撞密码的,虽然没被撞开(应该),但搞得系统卡卡的。关掉 公网 3389 用 vpn 连上来有点大题小作,换个端口应该就行(虽然也许还有没事找事全端口扫的家伙,不过比起专扫 3389 的应该少不少)。

修改注册表

直接新建一个 change_rdp_port.reg 文件,假设我们吧端口换到 3380,用一个 10 转 16 进制计算机算一下,3380 的 16 进制是 d34。那么文件内容为:

1
2
3
4
5
6
7
Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server\Wds\rdpwd\Tds\Tcp]
"PortNumber"=dword:00000d34

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp]
"PortNumber"=dword:00000d34

保存,双击运行即可。

修改防火墙

重启 windows server 就能生效。。。按下重启键你就凉了,还要对 windows server 默认开启的防火墙动手脚。

控制面板\系统和安全\Windows Defender 防火墙 中,找到高级设置 -> 入站规则。新建规则 -> 规则类型:端口 -> 应用于 tcp,特定本地端口填入 3380 -> 允许连接 -> 一路下一步,给 tcp 规则起个名字。搞掂后打开规则属性,在程序与服务 -> 程序 -> 此程序中填入:

1
%SystemRoot%\system32\svchost.exe

保存。

复制一遍该规则,粘贴后进入规则属性,改一下名字,在协议和端口中将 tcp 改为 udp。

点一下顶上名称栏的本地端口,给本地端口排个序,把原来的 3389 tcp 和 udp 端口禁用。ok,重启,通过 ip:3380 连入 rdp。

(21.3.17 更新) 或者,新建一个 ps1 文件,内容为:

1
2
New-NetFirewallRule -Name tcp-rdp -DisplayName 'rdptcp' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 3380
New-NetFirewallRule -Name udp-rdp -DisplayName 'rdpudp' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 3380

开启 ssh(21.4.1 更新)

防止 rdp 突然爆掉,有个后路(

前引:windows 开启 openssh-server | Bao’s 备忘录

安装

windows server 2012 r2 small disk 不支持 Add-WindowsCapability 这一类的命令。代替的方案有:

  1. 手动解压安装。从 Releases · PowerShell/Win32-OpenSSH 下载 OpenSSH-Win64.zip,解压到任意位置并添加到系统变量中,运行其中的 install-sshd.ps1

  2. 直接用 chocolatey 安装。参考:openssh · master · DarwinJS / ChocoPackages · GitLab

    1
    choco install openssh -params '"/SSHServerFeature"' 

修改 sshd_config

参考前引文章的修改方法。

打开管理员登录权限

1
PermitRootLogin yes

注释掉旧版密钥路径

1
2
#Match Group administrators
# AuthorizedKeysFile __PROGRAMDATA__/ssh/administrators_authorized_keys

关闭密码登录

1
PasswordAuthentication no

将公钥放到 C:\Users\zbttl\.ssh里面,改名为authorized_keys

修改端口,或者使用计划任务进行运行

在管理员账户下,通过刚才方法安装的 openssh 会自动启动服务,但这时候通过 22 端口还是没法登录。必须修改到 1000+ 的高位端口,继续修改 sshd_config:

1
2
#Port 22
Port 10022

然后重启服务。

1
2
net stop sshd
net start sshd

如果一定要用 22 端口,只能用 psexec 启动。(直接 sshd -d 会出和通过服务启动时一样的错误)

1
2
choco install psexec -y
psexec -s sshd.exe -d

不过要注意,用这种方法启动的终端,只能连一次。。。连完以后就会断掉,还要再手动开起来。解决方法是用 winsw 把这行命令做成服务,winsw 在 一步到位的 vps 从入门到放弃 | Bao’s 备忘录 frp 相关配置中我我曾经提过,有需求的读者自己实现吧。

其他

打开防火墙(继续用 22 的话可以忽略这一步,chocolatey 自己开开了)

1
New-NetFirewallRule -Name sshd -DisplayName 'OpenSSH Server (sshd)' -Enabled True -Direction Inbound -Protocol TCP -Action Allow -LocalPort 10999

更改默认命令行程序为 powershell

1
New-ItemProperty -Path "HKLM:\SOFTWARE\OpenSSH" -Name DefaultShell -Value "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -PropertyType String -Force

修改密钥权限参见前引,太长不写。

还有记得打开 azure web 那边的入站端口 10999 哦。

OneIndex app service version

我刚好有 office 365 家庭版,也试过挂在 vps 上,但 app service 这类 PaaS 我没那么熟,这次就折腾看看。

参考文章:

开服务既可以走 web 也可以走 cli:

建立 Web 应用(web,二选一)

  1. 在 azure 首页 -> 创建资源 -> 查看全部,搜索框中输入 web 应用,创建。

  2. 创建页面参考上一篇文章 github 学生包和 azure 羊毛 - 创建虚拟机,同样的最好不要和别的项目共用资源组。唯一要修改的地方是运行时堆栈选择 php 7.3。没提到的地方保持默认。最后点击下一步 -> 创建,等他创建完成。

建立 web 应用(CLI,二选一)

微软的 web 面板反应迟钝,也可以通过 CLI 创建,需要通过 azure-cli 软件。下文参考使用 Azure App Service 免费计划部署 Solo 博客过程记录 - 链滴

  1. 安装 azure-cli

    1
    choco install azure-cli -y
  2. 登录 Azure 账号

    1
    az login

    查看所有订阅,这里面 “id” 后面的这一串就是待会要用到的订阅 id

    1
    az account list --all

    选择一个education 订阅进行操作

    1
    az account set -s [订阅ID]

    创建部署用户(用户名密码自己起)

    1
    az webapp deployment user set --user-name [用户名] --password [密码]

    查看所有部署用户

    1
    az webapp deployment user show

    查看所有可用区域

    1
    az account list-locations

    创建资源组,-l 这里输入刚刚可用区域里面找到的相应区域名字,这里选择 East Asia(即香港区,其实部署在哪里无所谓啦,最后流量也不走服务器,目录查看并不太吃流量和速度)

    1
    az group create -l eastasia -n [资源组名称]

    创建免费的应用服务计划,注意这里 -n 参数和上面的 -n 参数含义不一样(毕竟 -n 应该是代表 new),这里的是服务器计划名称,资源组名称填在 -g。服务计划名称中不能含有下划线。

    1
    az appservice plan create -n [服务计划名称] -g [资源组名称] --sku FREE

    查看运行时堆栈

    1
    az webapp list-runtimes

    创建应用。这里 -n 又变成应用服务名称了,服务计划名称放在 -p(plan)。我用的是 powershell,后面 -r 这里需要双重转义。用 cmd 的填 -r "php|7.3" 就行。

    1
    az webapp create -g [资源组名称] -p [服务计划名称] -n [应用服务名称] -r '"php|7.3"'

导入项目

  1. 创建完毕后从 azure 面板资源组找到创建的应用服务和应用服务计划,点开应用服务。

  2. 找到左侧的部署中心,右边会显示「未配置 CI/CD」,顺着按钮转到设置。在设置一项 -> 源中选择本地 git 并保存。另外提一嘴,这里用 github 应该才是最方便的,但选 github 底下堆栈那里找不到 php,莫非是不支持?那就没辙了。

  3. 转到右侧的凭据,记下克隆 url,用户名和密码。用户名只用记以 $ 打头的后半部分(不知道为啥新版部署中心这里这么写,我头几次输用户名的时候疯狂报错,后来到旁边的经典部署中心才发现斜杠前面的部分是多余的,不过旧版部署中心不太好用)。

  4. 拉取 oneindex 项目到本地。oneindex 源项目已经被删掉挺久了。。。这里给出两个克隆 / 魔改版:

    后者是谷歌搜到的第一个,我翻了一下代码,又亲自部署了一下感觉没问题;前者来自 Newlearnerの自留地 之前的推荐(后续发现部署错误,疑似回调接口损坏)。

    1
    2
    3
    4
    git clone https://github.com/steven52880/Oneindex-Mod.git
    cd oneindex
    git remote add azure [部署URL]
    git push azure -f

    如果 git push 这一步密码不慎输错的话。。。有可能需要到 windows 的凭据管理器 -> windows 凭据中删除相应凭据回来再执行最后一步(直接修改可能不行)。

配置 OneIndex

在部署中心处点击右侧的浏览,进入 OneIndex 站点。如果进去的时候发现不是下面这个样子,多半是还在部署,等等吧,等日志中显示部署成功。

点击下一步,点击获取应用 id 和机密,按要求操作,不出意料第一个界面会返回 client secret 而第二个界面中有 client_id,回来填入即可。

如果不成功的话,可以尝试手动获取。其中一个框里面已经填上了网址,这就是待会要用到的回调 url。记下来。

「回到」 azure。这里的回到打引号是因为开服务的这个号可以完成使命了,你可以换另一个号来获取剩下的内容(当然继续用开服务的这个号也可以)。搜索并进入「应用注册」,名称随便填;受支持的账户类型选最长的那一个;重定向 url 就填我们刚刚获得的回调 url。

点击确定后跳转到概要,记下其中的应用程序(客户端) ID。这个是 OneIndex 注册界面中 Client_id 的值。

从左侧面板来到证书和密码,点新客户端密码,说明随便起,截止日期可选从不。点击添加后,这个值便是 OneIndex 注册界面中的 Client_secret。记得保存好,出了该页面再回来这个值就会被打码(不过也没什么,删掉再建就行)。

来到 api 权限,点击添加权限,看到那个大大的 microsoft Graph,点进去,选委托的权限,勾选 OpenId 类下的 offline_access,Files 类下的 Files.ReadFiles.Read.All 共三个权限,点击添加权限即可。

回到 OneIndex,填上这两个值即可。

后续按照流程绑定账号,不出意料就能进入管理界面了(默认密码 OneIndex)。完成部署。

其他注意事项

OneIndex 我只想共享两个目录的内容,但根目录下那么多文件夹一个个设置排除很麻烦,所以我干脆又做了一个 app service。部署的时候设置的 Client_id 和 client secret 可以反复使用,不用重新生成。

onedrive 目录类项目还有好多个变种,要换另一个试试的话,某些情况下直接导入到原来部署好的应用服务也可以生效,如果部署日志显示成功那就是可以。但也有很多情况需要重新删掉原来的应用服务重新建一个,比如要换 client_id 和 client_secret 的时候;不同的项目可能有不同的回调 url,如果用的同一个 client_id 的话,记得在对应的 client_id 应用 -> 身份验证中添加对应的回调 url。

目前能部署的貌似只有 OneIndex?多个版本的 OLAINDEX 用这个方法部署不上去,估计可能是什么依赖没装。