分类 电脑 下的文章

grub2 + 虚拟磁盘 或 grub2 + ntboot 启动 bios + gpt 上的 Windows 2022

感谢:wzy,wintoflash,minlearn

需求:主机商提供的产品存储超过2TB容量,且仅支持bios方式启动机子。Linux系统能在 bios + gpt 的环境中正常安装和运行,但 Windows 系统要求 bios + mbr 或 uefi + gpt 的组合,不支持 bios + gpt 的场景。

方案A:从网友 wzy 的博客来看,Windows的启动管理bootmgr.exe不认gpt分区,所以启动不了。解决方法是创建一个包含启动代码和文件的虚拟磁盘文件来启动Windows。缺点:无法Windows更新

方案B:从网友 minlearn 在无忧论坛里和 ntboot 作者 wintoflash 交流帖可知,通过 ntboot 是可以启动 bios + gpt 磁盘上已经安装的Windows系统(不支持Windows安装,会报“Windows安装程序 - 无法将 Window 配置为在此计算机的硬件上运行”的错误)。缺点:无法Windows更新

方案C:用grub4dos的ntloader来启动Windows。测试失败,用grub4dos的ntloader可以让gpt上的windows进入到桌面,但如计算机名、配置网卡静态IP地址等更改操作在重启系统后不生效。

这里记录一下实践的过程:

方案A:

  1. 创建一个vhd固定大小的虚拟磁盘,如 18 GB,名称为win2022.vhd
  2. 该vhd虚拟磁盘至少有三个分区,第一个是BIOS Partition,这个特别的分区是grub2必需的,可通过Linux系统里的cfdisk程序来创建。如下边的分区例子:

    Device                                Start                   End               Sectors               Size Type
    >>  /dev/sdb1                              2048                 32767                 30720                15M BIOS boot
    /dev/sdb2                             32768                647167                614400               300M EFI System
    /dev/sdb3                            647168                679935                 32768                16M Microsoft reserved
    /dev/sdb4                            679936              37746687              37066752              17.7G Microsoft basic data
  3. 创建第二个vhd固定大小的虚拟磁盘,本例的容量为64MB,名称为bootmgr.vhd。磁盘用MBR分区,创建一个主分区,且设置为活动分区
  4. 在Windows系统里附加两个vhd虚拟磁盘,假如本例中,第一个大的虚拟磁盘的NTFS分区盘符是M:,ESP分区盘符是L:;第二个虚拟磁盘的分区的分区盘符是B:
  5. 将已经安装好的Windows映像释放到NTFS分区中,如本例中的第4个分区M:,执行 bcdboot.exe M:\Windows /s L: /v /f uefi 将创建uefi相关的启动文件到 L: 分区 ;执行 bcdboot.exe M:\Windows /s B: /v /f bios 将创建bois相关的启动文件到 B: 分区;执行 bootsect /nt60 B: /mbr 将在B:上创建启动代码
  6. 分离第二个虚拟磁盘
  7. 将bootmgr.vhd的虚拟磁盘文件放到第一个vhd虚拟磁盘中的esp分区中L:
  8. 分离第一个虚拟磁盘
  9. 将win2022.vhd磁盘挂到一个debian系统的虚拟机里,挂载后,esp分区/dev/sdb2路径为/mnt/1,用grub-install将grub2安装到vhd磁盘。如例:grub-install --target=i386-pc /dev/sdb --boot-directory=/mnt/1;复制/usr/lib/syslinux/memdisk 文件 到esp分区/mnt/1
  10. 复制或创建一个grub的配置文件,放在grub目录里,配置文件需有bootmgr.vhd的启动项内容,如本例的部分内容:

     menuentry "bootmgr.vhd" {
    insmod part_msdos
    insmod part_gpt
    insmod fat
    insmod ntfs
    linux16 /memdisk raw
    initrd16 /bootmgr.vhd
    }

    11.正常的情况下,该包含有grub2,bootmgr.vhd和Windows的gpt vhd虚拟磁盘,能在VirtualBox的bios或efi虚拟机里启动

方案B:

  1. 下载ntboot的源码,通过grub-mkimage创建好grub2的core.img,再用grub-install安装到vhd磁盘。如例:grub-install --target=i386-pc /dev/sdb --boot-directory=/mnt/1 --directory=/home/liujia/grub/i386-pc/ 这例里,是将vhd磁盘挂到debian系统里安装grub2,/mnt/1路径是vhd的第2个分区,即esp分区 /home/liujia/grub/i386-pc/ 是ntboot源码的目录路径
  2. 将windows的安装光盘iso里的sources/boot.wim/1/Windows/Boot/PXE/bootmgr.exe文件提取出来,放到ESP分区中
  3. 复制或创建一个grub的配置文件,放在grub目录里,配置文件需有ntboot的启动项内容,如本例的部分内容:

    menuentry 'nbtoot' {
    insmod part_msdos
    insmod part_gpt
    insmod fat
    insmod ntfs
    set root='hd0,gpt2'
    ntboot --efi=/bootmgr.exe --win (hd0,gpt4);
    }
  4. 将已经安装好的Windows映像释放到NTFS分区中,如本例中的第4个分区,且Windows是从uefi环境中引导的(ESP中有Windows的相应目录和文件,如上边的步骤,执行 bcdboot.exe M:\Windows /s L: /v /f uefi
  5. 正常的情况下,该包含有grub2,ntboot和Windows的gpt vhd虚拟磁盘,能在VirtualBox的bios或efi虚拟机里启动

问题:因为Windows是已经安装的,所以如将这个win2022.vhd复制使用,Windows的SID、计算机名称等是一样的。微软建议用sysprep来生成新的SID,避免机子加域时遇到问题。

bios-gpt-2.png

参考:

在 iredmail 里批量添加邮箱用户

环境:debian11,iredmail-1.5.1。例子,创建user5@anqun.orguser6@anqun.org两个邮箱用户。

步骤:

  1. cd iRedMail-1.5.1/tools # 转到 iRedmail 安装目录中的tools子目录
  2. bash create_mail_user_SQL.sh user5@anqun.org 'mima881' >> user.sql
    bash create_mail_user_SQL.sh user6@anqun.org 'mima882' >> user.sql # 生成一个包含sql语句的文件。sql语句是创建user5和user6两个用户,且设置密码
  3. mysql -u root vmail < user.sql # 将此文件导入到vmail数据库中

参考:https://docs.iredmail.org/sql.create.mail.user.html

在 iredmail 里设置一个可以代收不存在用户邮件的邮箱 - catch-all

环境:debian11,iredmail-1.5.1。例子,将@anqun.org域中,不存在的用户邮件发到存在的admin@anqun.org 收件箱。

步骤:

  1. echo 'INSERT INTO forwardings (address, forwarding, domain, dest_domain) VALUES ('anqun.org', 'admin@anqun.org', 'anqun.org', 'anqun.org');' > catch.sql # 生成一个包含sql语句的文件
  2. mysql -u root vmail < catch.sql # 将此文件导入到vmail数据库中

参考:https://docs.iredmail.org/sql.create.catch-all.html

在 debian 11 里安装 iredmail 1.5.1

概要:需要在debian 11系统里安装 iredmail 1.5.1。本例是需要设置 anqun.org 的收件域。

先要解析好域名,如设置 a 记录 mail.anqun.org 到debian 11系统的公网IP,如 47.97.19.216;设置 mx 记录到 mail.anqun.org。

步骤:

  1. echo mail > /etc/hostname # 设置主机名为 mail
  2. echo 127.0.0.1 mail.anqun.org mail localhost localhost.localdomain > /etc/hosts # 设置完整的主机名为 mail.anqun.org
  3. wget https://github.com/iredmail/iRedMail/archive/refs/tags/1.5.1.tar.gz # 下载 iredmail 1.5.1 安装包
  4. tar xzvf 1.5.1.tar.gz # 解压缩安装包
  5. cd iRedMail-1.5.1 # 转到安装包目录
  6. bash iRedMail.sh # 开始安装
  7. iRedMail 安装欢迎界面
  8. 设置邮件存储目录,可保持默认,/var/vmail
  9. 选择web服务,可保持默认,nginx
  10. 选择存储邮件用户名的数据库类别,可选择 MariaDB
  11. 填写第一个电子邮局的域名,要与主机名区别开来,如本例的 mail.anqun.org
  12. 设置邮局管理员的密码,本例默认管理员用户名是:postmaster@mail.anqun.org
  13. 选择要安装的其它组件,可保持默认,安装 iRedAdmin(类似postfixadmin,可通过web浏览器管理邮局域),Roundcubemail(邮箱用户可通过浏览器收发邮件), Fail2ban
  14. 再次确认要安装的组件或功能。请选择y
  15. 询问是否启用防火墙。请选择n
  16. 完成iRedMail安装,会有相应的登录信息提示。之后,重启系统

参考:https://docs.iredmail.org/install.iredmail.on.debian.ubuntu.html

在 CentOS 7 宝塔面板软件环境中安装unixODBC和FreeTDS - 使用php的 odbc_connect 函数 连接 SQL Server 2000

需求:在CentOS7 的宝塔面板软件环境中,已经安装有 nginx + php7.3。需要通过如 $connect = odbc_connect("DRIVER=FreeTDS; Server=192.168.97.65; Port=1433; TDS_Version=7.1; Database=master", 'sa', 'aqtest'); 的php文件连接到 SQL Server 2000

尝试:

  1. 下载 unixODBC-2.3.9 源码文件。再配置、编译和安装。如本例,是将unixODBC安装到/usr/local/unixODBC的路径,所以在配置时,是 ./configure --prefix=/usr/local/unixODBC
  2. 下载 freetds-1.3.4 源码文件。再配置、编译和安装。如本例,是将FreeTDS安装到/usr/local/freetds的路径,在配置时,除了要加上自定义的安装路径,还要加上unixODBC的参数,如 ./configure --with-tdsver=7.4 --prefix=/usr/local/freetds --enable-msdblib --with-unixodbc=/usr/local/unixODBC
  3. 如果宝塔环境中,安装的php版本是7.3.33的,请下载 php-7.3.33 源码文件。解压后,在原宝塔的php配置参数基础上加 '--with-unixODBC=/usr/local/unixODBC' ,如本例,再编译和安装

    [root@localhost php-7.3.31]# './configure'  '--prefix=/www/server/php/73' '--with-config-file-path=/www/server/php/73/etc' '--enable-fpm' '--with-fpm-user=www' '--with-fpm-group=www' '--enable-mysqlnd' '--with-mysqli=mysqlnd' '--with-pdo-mysql=mysqlnd' '--with-iconv-dir' '--with-freetype-dir=/usr/local/freetype' '--with-jpeg-dir' '--with-png-dir' '--with-zlib' '--with-libxml-dir=/usr' '--enable-xml' '--disable-rpath' '--enable-bcmath' '--enable-shmop' '--enable-sysvsem' '--enable-inline-optimization' '--with-curl=/usr/local/curl' '--enable-mbregex' '--enable-mbstring' '--enable-intl' '--enable-ftp' '--with-gd' '--with-openssl=/usr/local/openssl' '--with-mhash' '--enable-pcntl' '--enable-sockets' '--with-xmlrpc' '--enable-soap' '--with-gettext' '--disable-fileinfo' '--enable-opcache' '--with-sodium' '--with-webp' '--with-unixODBC=/usr/local/unixODBC'
  4. 如果顺利,那么新版本的文件会覆盖原宝塔安装的php文件
  5. 新版本的phpinfo信息输出中,应该有unixODBC的信息详情,如:

    ODBC Support => enabled
    ODBC library => unixODBC
    ODBCVER => 0x0380
    ODBC_INCLUDE => -I/usr/local/unixODBC/include
    ODBC_LFLAGS => -L/usr/local/unixODBC/lib
    ODBC_LIBS => -lodbc
  6. php命令行可返回结果,如

    #php -r "var_dump(odbc_connect('DRIVER={freetds};SERVER=192.168.97.115;PORT=1433;DATABASE=master','sa','aqtest'));"
    resource(4) of type (odbc link)
  7. 在web里测试,php使用 odbc_connect 函数 也正常,如:

    [root@localhost local.anqun.org]# curl http://192.168.97.65/5.php
    master 1
    tempdb 2
    model 3
    msdb 4
  8. 测试文件5.php的内容如下(SQLServer 2008 Express):

    <?php
    
    # connect to 192.168.97.115 with a user "sa" and password "aqtest"
    $connect = odbc_connect("DRIVER=freetds;SERVER=192.168.97.115;PORT=1433 DATABASE=master",'sa','aqtest');
    
    # query the users table for all fields
    $query = "select * from sysdatabases";
    
    # perform the query
    $result = odbc_exec($connect, $query);
    
    # fetch the data from the database
    while(odbc_fetch_row($result)) {
    $field1 = odbc_result($result, 1);
    $field2 = odbc_result($result, 2);
    print("$field1 $field2\n");
    }
    
    # close the connection
    odbc_close($connect);
    
    ?>

dn_bt-php-unixodbc-freetds-sqlserver-1.png

参考: