Grow up

生活とプログラミング

.Net CoreをARM32 UbuntuのNginxで動かしてみた

f:id:knkomko:20190907221113p:plain:w450
Introducing .NET 5 | .NET Blog

はじめに

最近ARMアーキテクチャのCPUで動くNASを使う機会がありました。
.Net Core はARMアーキテクチャのCPUをサポートしているとの事だったので、動かすために準備した内容をまとめます。

Docker が使えたのでDockerイメージ上で.Net Coreを動かしました。

NASの仕様

OS : Alpine Linux
CPU : ARM32
メモリ : 1GB

Dockerイメージ

Ubuntu 16.4 LXC

開発環境

Windows10 Pro
VisualStudio2019
.Net Core SDK 2.1.3

.Net Core サポートOS

ARM32アーキテクチャのCPUではDebianUbuntuが使用できます。
f:id:knkomko:20190831022031p:plain:w450
core/2.1-supported-os.md at main · dotnet/core · GitHub

今回はイメージが見つけられた Ubuntu 16.4 LXC を使用しています。
以降の手順は Ubuntu でコマンドを実行しています。

1. パッケージの更新

以降の手順でパッケージのインストールに失敗する事を防ぎます。

apt-get update
apt-get install –y wget
2. .Net Framework のインストール
wget -qO- https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.asc.gpg
sudo mv microsoft.asc.gpg /etc/apt/trusted.gpg.d/
wget -q https://packages.microsoft.com/config/ubuntu/18.04/prod.list
sudo mv prod.list /etc/apt/sources.list.d/microsoft-prod.list
sudo apt-get install apt-transport-https
sudo apt-get update
3. .Net SDK のインストール
get https://download.microsoft.com/download/8/8/5/88544F33-836A-49A5-8B67-451C24709A8F/dotnet-sdk-2.1.300-linux-arm.tar.gz
mkdir -p $HOME/dotnet && tar zxf dotnet-sdk-2.1.300-linux-arm.tar.gz -C $HOME/dotnet
export PATH=$PATH:$HOME/dotnet
4. .NET SDK がインストール出来ているか確認
dotnet 
5. Ubuntu - C/C++ 開発ライブラリ(.Net Core動作環境)のインストール
sudo apt-get install libunwind8 icu-devtools
6. NET アプリケーションの作成とNginxによる公開

以下の記事を参考にNginxのインストールと公開の設定を行います。
www.aruse.net

Open SSL のインストール

dotnet run 実行時に Open SSL が必要だとエラーが出た場合はインストールが必要です。今回は arm32 で使用可能な Open SSL 1.0.2 をインストールしました。

OpenSSL のインストールで使う make と gcc コマンドをインストール。

sudo apt-get install –y make
sudo apt-get install –y gcc

OpenSSLに使用されているファイル圧縮・展開ライブラリをインストール。

sudo apt install zlib1g
sudo apt install zliblg-dev

OpenSSLのインストール。

wget https://www.openssl.org/source/openssl-1.0.2.tar.gz
tar xvf openssl-1.0.2.tar.gz
cd openssl-1.0.2
./config zlib shared no-ssl2
make && sudo make install

再度 dotnet run を実行してアプリが動くことを確認します。

.Net CoreでExcelファイルをWebからダウンロードする方法

はじめに

WebからExcelファイルがダウンロード出来るのか疑問に思いやってみました。
今回はjqueryを使わずに出来たのでまとめてみます。

前回は圧縮ファイルのダウンロードにjqueryを使っていました。
knkomko.hatenablog.com

動作

C:\work\sample.xlsx にファイルを保存しています。
こちらのExcelファイルをWebからダウンロードしています。
f:id:knkomko:20190901235652p:plain:w450

Download ボタンを左クリックするとファイルがダウンロードできます。
f:id:knkomko:20190901235509p:plain:w450

ダウンロードしたファイルはダウンロードフォルダに保存されます。
f:id:knkomko:20190902001313p:plain:w450

文字化けも無くファイルが開けます。
f:id:knkomko:20190901235844p:plain:w450

開発環境

VisualStudio2019
MicrosoftOffice2016

ソースコード

ExcelファイルのダウンロードではFileメソッドの引数に Octet を指定します。

Controllers\FormController.cs

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace ExcelDownloadWebApp.Controllers
{
    public class FormController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public IActionResult ExcelFileDownload()
        {
            var file = System.IO.File.ReadAllBytes(@"C:\work\sample.xlsx");
            return File(file, System.Net.Mime.MediaTypeNames.Application.Octet, "sample.xlsx");
        }
    }
}

ボタン押下時にFormController の ExcelFileDownload メソッドを呼び出します。
View\Form\Index.cshtml

<h2>ExcelFileDownload</h2>
<form class="form-horizontal" asp-controller="Form" asp-action="ExcelFileDownload">
    <input name="submit" value="Download" type="submit" />
</form>
ZIPファイルのダウンロード

上記と同じ方法でjqueryを使わなくてもZIPファイルがダウンロードできました。
f:id:knkomko:20190902001348p:plain:w450

FormControllerにあるExcelFileDownload()のファイル名を変更しています。

Controllers\FormController.cs
>|cs|
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;

namespace ExcelDownloadWebApp.Controllers
{
    public class FormController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public IActionResult ExcelFileDownload()
        {
            var file = System.IO.File.ReadAllBytes(@"C:\work\sample.zip");
            return File(file, System.Net.Mime.MediaTypeNames.Application.Octet, "sample.zip");
        }
    }
}

HTTP Error 502.5 - Process Failure の解決方法

f:id:knkomko:20190825210938p:plain:w450

はじめに

.Net Core アプリをIISに発行してブラウザで確認するとエラーになりました。
今回は.Net CoreのSDKのバージョンを合わせる事で解決できたのでまとめます。

開発環境

Windows10 Pro
VisualStudio 2019
.Net Core SDK 2.1.700

原因

.Net Core SDK のバージョンが開発環境とサーバで違っていました。

バージョンの確認には以下のコマンドを使用します。

dotnet --version

開発環境
.Net Core SDK 2.1.700
f:id:knkomko:20190825212822p:plain:w450

サーバ
.Net Core SDK 2.1.300
f:id:knkomko:20190825212838p:plain:w450

解決方法

サーバに開発環境と同じバージョンの.Net Core SDKをインストールします。

1. SDK のダウンロード

microsoft のサイトから該当バージョンの.Net Core SDKをダウンロードします。
Download .NET Core 2.1 (Linux, macOS, and Windows)

今回は 2.1.700 のバージョンをダウンロードしました。
f:id:knkomko:20190825212406p:plain:w450

2. インストール

[Install]ボタンをクリックしてSDKをインストールします。
f:id:knkomko:20190825213926p:plain:w450

インストール後に再度バージョンを確認します。
無事 2.1.300 から 2.1.700 に変わった事が分かります。
f:id:knkomko:20190825213415p:plain:w450

3. IISの再起動

以下のコマンドでIISを再起動します。

iisreset

f:id:knkomko:20190825214143p:plain:w450

IISを再起動することで新しいSDKのバージョンを認識させています。

4. 確認

Webページにアクセスできることを確認します。
f:id:knkomko:20190825214553p:plain:w450

SDKの削除

コントロールパネルの「プログラムの削除」から削除できます。
f:id:knkomko:20190825214846p:plain:w450

プログラムの削除内のSDKをダブルクリックすると以下の画面が表示されます。
[Uninstall]ボタンをクリックするとアンインストールされます。
f:id:knkomko:20190825215014p:plain:w450

AWS EC2 + RDS サーバー環境の構築からCIDRを学ぶ

はじめに

EC2 + RDS の環境構築に成功したので復習をしてみます。
構築するうえでCIDRを理解することに一番時間がかかりました。
そのため、今回は CIDR Block に重点をおいてまとめたいと思います。

CIDR とは

「Classless Inter-Domain Routing」の略でサイダーと読みます。
ネットワーク部とホスト部を任意の値で区切れる事が特徴です。
任意の値で区切れるため、IPアドレスを効率的に使用できます。

ネットワーク部とホスト部はビット単位で区切られるので、
分かり易いように下の図では10進数のIPアドレスを2進数表記にしています。

f:id:knkomko:20190820123943p:plain:w450
f:id:knkomko:20190820204127p:plain:w450

例1をCIDRで書き表すと「123.45.67.89/23」になります。
「/23」がネットワーク部のビット数を表しています。

CIDRからホスト部を知るにはIPアドレスの全長からネットワーク部を引きます。
「123.45.67.89/23」でホスト部を求めると、IPアドレスの全長32ビットから
ネットワーク部の23ビットを引いた残りの9ビットがホスト部になります。

ネットワーク部が一致するIPアドレスは同じネットワークのIPアドレスです。
ホスト部はデバイスを識別する為にデバイスごと一意の値が割り当てられます。

クラスフルとは

ちなみにCIDRが使われる前は「クラスフル」が一般的でした。
クラスフルではネットワーク部とホスト部を決められた値で区切ります。
ホストアドレスが大きいと使われないIPアドレスがでる事がデメリットです。

f:id:knkomko:20190820123943p:plain:w450
f:id:knkomko:20190820204102p:plain:w450

AWS EC2 + RDS 構築手順

以下のサイトを参考に構築を行いました。
【AWS 再入門】EC2 + RDS によるミニマム構成なサーバー環境を構築してみよう – PSYENCE:MEDIA

サイトを参考に構築手順を書き出すと以下の8つになります。

1. VPCの作成
2. Subnet の作成
3. Internet Gateway の作成
4. Route Table の作成
5. Security Group の作成
6. DBSubnet Group の作成
7. RDSインスタンスの新規立ち上げ
8. EC2インスタンスの新規立ち上げ

1. VPCの作成、2.Subnetの作成 でCIDRを設定します。
CIDRを設定する2つの手順を抜粋して解説をまとめます。
その他の解説ついては参考サイトをご確認ください。

1.VPCの作成

VPCはデータの転送経路となる仮想のネットワーク環境を用意できます。
CIDRを設定するのですが、IPアドレスはEC2やRDSごとに必要になるため
IPアドレスが枯渇するとEC2やRDSが増やせなくなるため注意が必要です。

今回CIDRには 10.0.0.0/16 を指定していました。
設定したCIDRからホスト部を求めた結果は以下の通りです。

f:id:knkomko:20190816131056p:plain:w550

10.0.0.0/16 では 64,770 個のIPアドレスが使えます。
使用できるIPアドレスは、ホストアドレスの範囲 10. 0. 0. 1~10. 0.255.254 です。

IPアドレス・サブネットマスク計算ツール

上記のようなサイトを活用する事で簡単に計算ができます。

2.Subnet の作成

サブネットとは「1つのネットワークを複数のネットワークに分割する」です。
サブネットとは - コトバンク

外部に公開するEC2用のサブネットと、外部に公開しないRDS用のサブネットを作成しています。
EC2はWebアプリを配置して全世界からアクセスするために公開をして
RDSはEC2からアクセス出来ればよいので外部に公開していません。
①サブネット化 のメリットの理解 – ランスルネット

今回サブネットは3つに分けるため、それぞれにCIDRを指定します。
サブネットのホスト部をそれぞれ求めてみます。

public subnet: web-server の CIDR Block は 10.0.0.0/24 なので使用可能なIPアドレスの範囲は 10.0.0.1 ~ 10.0.0.254 で 254個です。
f:id:knkomko:20190816161111p:plain:w550

private subnet: db1 の CIDR Block は 10.0.1.0/24 なので使用可能なIPアドレスの範囲は 10.0.1.1 ~ 10.0.1.254 で 254個です。
f:id:knkomko:20190816161152p:plain:w550

private subnet: db2 の CIDR Block は 10.0.2.0/24 なので使用可能なIPアドレスの範囲は 10.0.2.1 ~ 10.0.2.254 で 254個です。
f:id:knkomko:20190816161441p:plain:w550

まとめ

EC2 + RDS を使用する場合にはVPC内に3つのサブネットを作成するため「10.0.0.1~10.0.255.254」のIPアドレスが使用できるようにCIDR Blockを「/16」と指定していた事が分かりました。
IPアドレス領域を有効活用するためにCIDRを使用しているため、IPアドレス領域に無駄が生じないようCIDRを設定することが重要です。

Windows10の共有フォルダが見れない場合の解決方法(0x80070035)

はじめに

Windows10 をクリーンインストールしたら共有フォルダが見れなくなりました。
レジストリエディタから値を変更することで解決できたので書き残します。

状況

クリーンインストールする前は共有フォルダが見れていた。
Pingタイムアウトする。
・ネットワーク(エクスプローラ)からサーバーのパソコン名は確認できる。

検討すべき解決方法

こちらは解決した後に調べた方法なので試してはいません。
検討すべき理由として情報源がmicrosoftのコミュニティのため適切だと考えます。

ワークグループによるファイルの共有では、共有フォルダを提供しているパソコンに登録済みのアカウントでアクセスする必要があります。よって、共有フォルダを提供しているパソコンに同じアカウント名とパスワードで自分のアカウントを登録してあれば、自動的にログインすることができます。

answers.microsoft.com

試した解決方法

microsoftコミュニティでこちらの解決方法は以下のような指摘がありました。

ゲストによる無制限のアクセスは迷惑ソフトウェアに悪用されて迷惑ソフトウェアの感染に利用されていることも多いので避けた方がいいです。

そのためセキュリティリスクについて熟考のうえお試しください。

1. レジストリエディタ (regedit) を起動する。
[ウィンドウズマーク] + [R] キーを同時に押します。
f:id:knkomko:20190819213853j:plain:w350

名前に「regedit」と入力して[OK]ボタンをクリックします。
f:id:knkomko:20190819213511p:plain:w350

2. AllowInsecureGuestAuthの値を0から1に変更する
フォルダが深いため以下のアドレスをレジストリエディターにコピーします。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanWorkstation\Parameters
f:id:knkomko:20190819214459p:plain:w350

既に AllowInsecureGuestAuth がある場合は次の手順に進みます。
背景を右クリック → 新規 → DWORD 32ビット値 (D) を左クリックします。
f:id:knkomko:20190819214843p:plain:w350

AllowInsecureGuestAuth を右クリック → 修正(M) を左クリックします。
f:id:knkomko:20190819215125p:plain:w350

値のデータ(V) を 1 に変更して[OK]を左クリックします。
f:id:knkomko:20190819215532p:plain:w350

3. パソコンを再起動
再起動後に共有フォルダが閲覧できるか確認をして終了です。

AllowInsecureGuestAuthとは

SMB クライアントが SMB サーバーに安全でないゲスト ログオンを許可するかどうかを指定します。

AllowInsecureGuestAuth | Microsoft Docs

SMB とは

ネットワークを通じてファイル共有やプリンタ共有を実現するプロトコルである。

SMB | ネットワーク | IT用語辞典 | 日立ソリューションズ

AWS RDS Oracle に C# ネイティブアプリから接続する

f:id:knkomko:20190815020721p:plain:w450

はじめに

RDSのOracleを使う機会があったので接続方法についてまとめます。
今回は Oracle Client をインストールしないミドルウェアで接続しました。
Windows Form アプリケーションを使用して確認をしています。

動作環境

VisualStudio2019
.NET Framework 4.6
RDS Oracle 11.2.0.4.v21

OLEDBを使用した接続 (不採用)

OLEDBを使用すると以下のようなエラーが表示されました。

System.InvalidOperationException: The 'OraOLEDB.Oracle' provider is not registered on the local machine.

OLEDBを使用した接続では Oracle Client のインストールが必要のようです。
stackoverflow.com

using System;
using System.Data;
using System.Windows.Forms;

using System.Data.OleDb;

namespace OracleSample
{
    public partial class Form1 : Form
    {
        private const string HostName = "hostName";
        private const string ServiceName = "serviceName";
        private const string UserName = "userName";
        private const string Password = "password";

        public Form1()
        {
            InitializeComponent();
        }

        // OLEDB ExecuteNonQuery
        private void Button3_Click(object sender, EventArgs e)
        {
            string sql = TxtBox1.Text;
            using (OleDbConnection connection = new OleDbConnection("Provider=OraOLEDB.Oracle;Data Source=" + ServiceName + ";User Id=" + UserName + ";Password = " + Password + ";OLEDB.NET=True"))
            {
                OleDbCommand command = new OleDbCommand(sql, connection);
                connection.Open();
                command.ExecuteNonQuery();
                connection.Close();
            }
        }
        // OLEDB Fill
        private void Button4_Click(object sender, EventArgs e)
        {
            DataTable dataTablee;
            string sql = TxtBox2.Text;
            using (OleDbConnection connection = new OleDbConnection("Provider=OraOLEDB.Oracle;Data Source=" + ServiceName + ";User Id=" + UserName + ";Password = " + Password + ";OLEDB.NET=True"))
            {
                OleDbCommand command = new OleDbCommand(sql, connection);
                OleDbDataAdapter adapter = new OleDbDataAdapter(command);
                connection.Open();
                adapter.Fill(dataTable);
                connection.Close();
            }
            DataGridView001.DataSource = dataTable;
        }
    }
}
ODP.NET を使用した接続 (採用)

ODP.NET を使用することで Oracle Client のインストールが不要になります。

ODP.NET を使用するには以下のライセンスに同意する必要があります。
Oracle Technology Network Development and Distribution License Terms

NuGetにてdllをインストールして使用します。
https://www.nuget.org/packages/Oracle.ManagedDataAccess/

using System;
using System.Data;
using System.Windows.Forms;

using Oracle.ManagedDataAccess.Client; // ODP.NET Oracle managed provider

namespace OracleSample
{
    public partial class Form1 : Form
    {
        private const string HostName = "hostName";
        private const string ServiceName = "serviceName";
        private const string UserName = "userName";
        private const string Password = "password";
        private string connectstring = "Data Source = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = " + HostName + ")(PORT = 1521))(CONNECT_DATA = (SERVER = DEDICATED)(SERVICE_NAME = " + ServiceName + "))); User Id = " + UserName + "; Password = " + Password + ";Connection Timeout = 1500;";

        public Form1()
        {
            InitializeComponent();
        }

        // ODP.NET ExecuteNonQuery
        private void Button1_Click(object sender, EventArgs e)
        {
            string sql = TxtBox1.Text;
            using (OracleConnection connection = new OracleConnection(connectstring))
            {
                OracleCommand command = new OracleCommand(sql, connection);
                connection.Open();
                command.ExecuteNonQuery();
                connection.Close();
            }
        }
        // ODP.NET Fill
        private void Button2_Click(object sender, EventArgs e)
        {
            DataTable dataTable;
            string sql = TxtBox2.Text;
            using (OracleConnection connection = new OracleConnection(connectstring))
            {
                OracleCommand command = new OracleCommand(sql, connection);
                OracleDataAdapter adapter = new OracleDataAdapter(command);
                connection.Open();
                adapter.Fill(dataTable);
                connection.Close();
            }

            DataGridView001.DataSource = dataTable;
        }
    }
}
遭遇したエラー

1.SocketException (0x80004005)
ファイアウォールやネットワーク設定が原因の可能性があります。
私の場合はRDSのポートを開放することで解決できました。

System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond [IP address]

forums.asp.net

2. NetworkException (0x000030E2)
接続文字列に使用しているサービス名が間違っていました。

OracleInternal.Network.NetworkException (0x000030E2): ORA-12514: TNS:listener does not currently know of service requested in connect descriptor

stackoverflow.com

RDS → 設定 で表示されるインスタンスからサービス名が確認できます。
インスタンス内の「DB名」をサービス名に指定することで接続できました。
f:id:knkomko:20190814144517p:plain:w350

UNMOUNTABLE_BOOT_VOLUME の HDD からデータを取り出す方法

f:id:knkomko:20190730210856p:plain:w500

はじめに

社内で使われているノートパソコンのOSが起動しなくなりました。
リカバリーモード、自動修復、通常起動、どれを試してもダメでした。
それでも最終的にはHDDからデータを取り出せたので書き残しておきます。

社内で使われているノートパソコン

dynabook B554
f:id:knkomko:20190730231819j:plain:w350
dynabook 最新製品ラインアップ | dynabook(ダイナブック)

注意点

データを取り出せる100%の保証はありませんので最終手段と考えてください。
そのためうまくいかなくても自己責任でお願いします。
今回試した内容はメーカー保証の対象外です。

使ったもの

ノートパソコンのHDDを外付けドライブとして使うケーブルです。

HDDをUSB SATA&IDE-USB2.0変換アダプタケーブル UD-500SA

HDDをUSB SATA&IDE-USB2.0変換アダプタケーブル UD-500SA

データを取り出す方法

通電による怪我やHDDの破損が考えられるため、バッテリーパックを抜くと共にACアダプタも抜きましょう。
青色部分がバッテリーパックだったので外しました。

次に、HDDをノートパソコンから取り外します。
赤色部分がHDDのカバーになっていたので、外すとHDDが見えました。
HDDは取り付けられ方を観察してうまく外します。

f:id:knkomko:20190730234249p:plain:w350
https://dynabook.com/pc/catalog/satellit/manupdf/gx1c0012g210_prt.pdf


取り外したHDDとUSBをケーブルで接続します。
f:id:knkomko:20190730230339p:plain:w350

接続すると外部ドライブとして認識されます。
今回は G: ドライブとして認識されました。
運が良いと認識されたドライブを開くとデータを取り出せるかもしれません。
f:id:knkomko:20190730223132p:plain:w350

私の場合はドライブを開くと以下の様なエラーメッセージが表示されました。

G:\ にアクセスできません。

パラメータが間違っています。

ドライブ G:\ を使うにはフォーマットする必要があります。


次にコマンドプロンプトから認識されたドライブに chkdsk を実行します。
G: の部分は認識されたドライブに合わせて変更してください。

chkdsk G: /f /r

コマンドの使用については以下のHPのナレッジベースを参考にしました。
support.hp.com

コマンドのプロパティについては以下のサイトをご確認ください。
social.technet.microsoft.com

以下のように処理が進み、私の場合は1時間で終了しました。
f:id:knkomko:20190730222046p:plain:w450

再度、ドライブを開いてデータを取り出せるか確認を行って終了です。
今回の方法で取り出せない場合は、有償サービスの利用も手だと思います。