CentOS 7/8 源码安装 mbedtls 2.16.3, 解决configure: error: mbed TLS libraries not found. 错误。

1、下载并解压

wget https://tls.mbed.org/download/mbedtls-2.16.3-gpl.tgz
tar -xf mbedtls-2.16.3-gpl.tgz
cd mbedtls-2.16.3

备用下载地址:https://down.24kplus.com/linux/mbedtls/mbedtls-2.16.3-gpl.tgz

2、编译安装

make
make DESTDIR=/usr install
ldconfig

如果出现 make[1]: python2: Command not found 错误,执行:

yum -y install python2

如果出现 /usr/bin/env: ‘perl’: No such file or directory 错误,执行:

yum -y install perl

CentOS 安装 shadowsocks-libev, 本教程仅提供学习,请勿用于商业用途和不法行为。

如果你觉得安装步骤繁杂,可以试试 一键安装 shadowsocks-libev

1、准备编译环境

CentOS 7

yum install gcc gettext autoconf libtool automake make pcre-devel asciidoc xmlto c-ares-devel libev-devel libsodium-devel mbedtls-devel -y

CentOS 8

yum install gcc gettext autoconf libtool automake make pcre-devel asciidoc xmlto c-ares-devel libev-devel -y

2、获取shadowsocks-libev源码, 并安装

yum install git
git clone https://github.com/shadowsocks/shadowsocks-libev.git
cd shadowsocks-libev
git submodule update --init
./autogen.sh && ./configure --disable-documentation && make
sudo make install

如果出现 error: The Sodium crypto library libraries not found 错误,安装 libsodium

如果出现 error: mbed TLS libraries not found. 错误,安装 mbedtls

3、 创建配置文件

sudo mkdir /etc/shadowsocks-libev
sudo vi /etc/shadowsocks-libev/config.json

复制粘贴如下内容(注意修改密码“password”):

{
     "server":"0.0.0.0",
     "server_port":8388,
     "local_port":1080,
     "password":"password",
     "timeout":600,
     "method":"aes-256-cfb" ,
     "fast_open": false
 }

4、创建Shadowsocks-libev.service配置文件

sudo vi /etc/systemd/system/shadowsocks-libev.service

复制粘贴:

[Unit]
Description=Shadowsocks-libev Server
Documentation=https://shadowsocks.org/en/
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/ss-server -c /etc/shadowsocks-libev/config.json -u
Restart=on-abort

[Install]
WantedBy=multi-user.target

5、启动 Shadowsocks-libev 服务

sudo systemctl start shadowsocks-libev

6、设置开机启动

sudo systemctl enable shadowsocks-libev

至此, Shadowsocks-libev服务器端的基本配置已经全部完成了!

设置防火墙开放端口

开放 tcp/udp 8388 端口

firewall-cmd --zone=public --add-port=8388/tcp --permanent
firewall-cmd --zone=public --add-port=8388/udp --permanent

重新载入防火墙配置,使规则生效

sudo systemctl restart firewalld

优化 Shadowsocks-libev 直达航班: 优化 shadowsocks-libev 网络

最后送上Windows 客户端 Shadowsocks-4.1.7.1.zip

using System;
using System.Drawing;
using System.Drawing.Imaging;

namespace Utility
{
    public class ImageUtil
    {
        ///<summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径(物理路径)</param>
        /// <param name="thumbnailPath">缩略图路径(物理路径)</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>
        /// <param name="mode">生成缩略图的方式</param>    
        public static void MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, string mode)
        {
            Image originalImage = Image.FromFile(originalImagePath);

            int towidth = width;
            int toheight = height;

            int x = 0;
            int y = 0;
            int ow = originalImage.Width;
            int oh = originalImage.Height;

            switch (mode)
            {
                case "HW"://指定高宽缩放(可能变形)                
                    break;
                case "W"://指定宽,高按比例                    
                    toheight = originalImage.Height * width / originalImage.Width;
                    break;
                case "H"://指定高,宽按比例
                    towidth = originalImage.Width * height / originalImage.Height;
                    break;
                case "Cut"://指定高宽裁减(不变形)                
                    if ((double)originalImage.Width / (double)originalImage.Height > (double)towidth / (double)toheight)
                    {
                        oh = originalImage.Height;
                        ow = originalImage.Height * towidth / toheight;
                        y = 0;
                        x = (originalImage.Width - ow) / 2;
                    }
                    else
                    {
                        ow = originalImage.Width;
                        oh = originalImage.Width * height / towidth;
                        x = 0;
                        y = (originalImage.Height - oh) / 2;
                    }
                    break;
                default:
                    break;
            }
            //新建一个bmp图片
            Image bitmap = new Bitmap(towidth, toheight);
            //新建一个画板
            Graphics g = System.Drawing.Graphics.FromImage(bitmap);
            //设置高质量插值法
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBilinear;
            //设置高质量,低速度呈现平滑程度
            //g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQualityBilinear
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            //清空画布并以透明背景色填充
            g.Clear(Color.Transparent);
            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight), new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel);
            try
            {
                //以jpg格式保存缩略图
                bitmap.Save(thumbnailPath, ImageFormat.Jpeg);
            }
            catch (System.Exception e)
            {
                throw e;
            }
            finally
            {
                originalImage.Dispose();
                bitmap.Dispose();
                g.Dispose();
            }
        }
    }
}

这是微软官方提供的解决方案,支持简体中午,繁体中文,韩语和日语。

需要安装依赖的 Visual Studio International Pack

下载地址:https://www.microsoft.com/zh-CN/download/details.aspx?id=15251

using System;
using System.Data;
using System.Configuration;
using Microsoft.International.Converters.PinYinConverter;

namespace Utility.Convert
{
    /// <summary>
    ///ChineseConvert 的摘要说明
    /// </summary>
    public class ChineseConvert
    {
        public ChineseConvert() { }

        /// <summary>
        /// 汉字转化为拼音
        /// </summary>
        /// <param name="str">汉字</param>
        /// <returns>全拼</returns>
        public static string GetPinyin(string str)
        {
            string r = string.Empty;
            foreach (char obj in str)
            {
                try
                {
                    ChineseChar chineseChar = new ChineseChar(obj);
                    string t = chineseChar.Pinyins[0].ToString();
                    r += t.Substring(0, t.Length - 1);
                }
                catch
                {
                    r += obj.ToString();
                }
            }
            return r;
        }

        /// <summary>
        /// 汉字转化为拼音首字母
        /// </summary>
        /// <param name="str">汉字</param>
        /// <returns>首字母</returns>
        public static string GetFirstPinyin(string str)
        {
            string r = string.Empty;
            foreach (char obj in str)
            {
                try
                {
                    ChineseChar chineseChar = new ChineseChar(obj);
                    string t = chineseChar.Pinyins[0].ToString();
                    r += t.Substring(0, 1);
                }
                catch
                {
                    r += obj.ToString();
                }
            }
            return r;
        }

    }
}

/// <summary>
/// 判断是否是图片
/// </summary>
public static bool IsPicture(Stream stream)
{
	try
	{
		byte[] buffer = new byte[2];
		stream.Read(buffer, 0, 2);
		string fileClass = buffer[0].ToString() + buffer[1].ToString();

		//255216是jpg;7173是gif;6677是BMP,13780是PNG;7790是exe,8297是rar   
		string[] fileType = { "255216", "7173", "13780", "6677" };
		return fileType.Contains(fileClass);
	}
	catch
	{
		return false;
	}
}

public class FileUtil
{
	[DllImport("kernel32.dll")]
	private static extern IntPtr _lopen(string lpPathName, int iReadWrite);

	[DllImport("kernel32.dll")]
	public static extern bool CloseHandle(IntPtr hHandle);


	private const int OF_READWRITE = 2;
	private const int OF_SHARE_DENY_NONE = 0x40;
	private static readonly IntPtr HFILE_ERROR = new IntPtr(-1);
	
	/// <summary>
	/// 查看文件是否被占用
	/// </summary>
	/// <param name="filePath">文件路径</param>
	/// <returns></returns>
	public static bool IsOccupied(string filePath)
	{
		IntPtr vHandle = _lopen(filePath, OF_READWRITE | OF_SHARE_DENY_NONE);
		if(vHandle == HFILE_ERROR)
		{
			return true;
		}
		CloseHandle(vHandle);
		return false;
	}
}

微软官方从.NET Framework 4之后不再支持System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(string password, string passwordFormat)方法。MD5加密需要自行实现。需要注意的是该方法加密结果是小写,而
HashPasswordForStoringInConfigFile加密结果是大写

public static string MD5Encrypt(string input)
{
	StringBuilder builder = new StringBuilder();
        using (MD5CryptoServiceProvider md5Crypto = new MD5CryptoServiceProvider())
        {
            byte[] data = md5Crypto.ComputeHash(Encoding.UTF8.GetBytes(input));
            for (int i = 0; i < data.Length; i++)
            {
                builder.Append(data[i].ToString("x2"));
            }
        }
        return builder.ToString();
}

using System;
using System.Text;
using System.Security.Cryptography;

namespace Utility.Security
{
    /// <summary>
    /// DES加密/解密类。
    /// </summary>
    public class DESEncrypt
    {
        /// <summary> 
        /// 加密数据 
        /// </summary> 
        public static string Encrypt(string Text, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            byte[] inputByteArray;
            inputByteArray = Encoding.Default.GetBytes(Text);
            des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateEncryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            StringBuilder ret = new StringBuilder();
            foreach (byte b in ms.ToArray())
            {
                ret.AppendFormat("{0:X2}", b);
            }
            return ret.ToString();
        }

        /// <summary> 
        /// 解密数据 
        /// </summary> 
        public static string Decrypt(string Text, string sKey)
        {
            DESCryptoServiceProvider des = new DESCryptoServiceProvider();
            int len;
            len = Text.Length / 2;
            byte[] inputByteArray = new byte[len];
            int x, i;
            for (x = 0; x < len; x++)
            {
                i = Convert.ToInt32(Text.Substring(x * 2, 2), 16);
                inputByteArray[x] = (byte)i;
            }
            des.Key = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            des.IV = ASCIIEncoding.ASCII.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(sKey, "md5").Substring(0, 8));
            System.IO.MemoryStream ms = new System.IO.MemoryStream();
            CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);
            cs.Write(inputByteArray, 0, inputByteArray.Length);
            cs.FlushFinalBlock();
            return Encoding.Default.GetString(ms.ToArray());
        }
    }
}