プログラマーのメモ書き

伊勢在住のプログラマーが気になることを気ままにメモったブログです

QNAP TS-251+ の設定(主に公開設定周り)

自宅のファイルサーバーとして、何台かのNASを使っているのですが、このたび、QNAP の TS-251+ を導入することにしました。 元々は、Netgear のNASばっかりだったのですが、もやし工房さんの記事を見て、Dockerが使えるのと、Netgear の NASでS3にバックアップを取れなさそうだったので、今回はQNAPを選んでみました。

www.moyashi-koubou.com

あ、Netgearの件は少し前に調べたので今は状況が異なっているかもしれません。なのと、GUIで簡単に設定するのがないだけで、SSHでログインして自分でS3へのバックアップを実行するようにすれば全然問題なく実現できると思います。

まずは、Dockerを使い始める前に、初期設定(主に公開設定周り)した話をまとめておきます。

あと、試したのは下記になります。

  • QNAP TS-251+
  • QTS 4.2.2

セットアップ

筐体を開けると、最近の機械の御多分に漏れず、簡単設定の方法が書かれた紙が入っていました。 本体にネットワークケーブルとHDDを追加して、電源を入れて、PCのブラウザで https://start.snap.com にアクセスして、筐体に書かれたアクセスコードを入力すればOK!

で、画面の設定に従って、必要事項を入力していけばいい・・・はずなのですが、この時点でいろいろと聞かれるので、まずこれが分かりにくい。 初期設定だけなら大したことしないだろうと思っていたので、画面キャプチャしなかったので、詳細を覚えてないのですが、いくつか設定する項目がありました。

  • myqnapcloud.com のアカウント登録(e-メールアドレス、パスワード)
  • myqnapcloud.com 上で使うデバイス(NAS)の名前
  • NAS 本体の名前
  • NAS の管理者用パスワード
  • NTP サーバー名

その他は確かデフォルト設定だったと思います。

で、一番わかりにくかったのが、(大して下調べもしてなかったのが原因ですが)myqnapcloud.com のアカウントって何?というところでした。 まあ、あとから、いろいろ調べてわかったのが、QNAPのNASをインターネット経由でアクセス可能とし、主にその際の公開設定などを行うためのサービスとなるようです。 NAS本体のセットアップだけを行うと思って、作業を開始していたので、この設定も同時に行わないといけないのに、ちょっとびっくりです。まあ、仕方ないのかな?もし、次にQNAPのNASを入れるときなったら、インターネット経由ではなく、ローカル環境で閉じた形でやってみるかな?

ストレージ設定

いろいと機能を試す間、ストレージにはとりあえず1TBのHDDを1台入れました。 設定方法はたいして覚えてないのですが、QTSデスクトップから『ストレージマネージャ』を起動して、あれこれしたように思います。

ただ、割り当ては、1TBまるまるストレージ領域として割り当てたのですが、システムがスナップショットなどに200GB近く予約してしまい、思ったよりユーザー領域が少なくなった印象でした。もっとも、このあたりの割り当て量はいろいりと変えられそうなので自分の目的に合わせて調整すれば良いかなと思います。

公開設定

で、セットアップ時に気になった myqnapcloud.com のアカウントですが、初期状態では NAS にインターネット経由で接続可能です。 試しに、myqnapcloud.com でデバイス名(公開用のNASの名前)を入力して検索すると、見事に表示されてしまいます。

f:id:junichim:20161004095759p:plain

ここで、 QTS Desktop を選択すると、なんと!NASの管理画面に入れてしまいます(もちろん、ユーザー名とパスワードは必要です)。同じく、File Station を選べば、NASに保存してあるファイルにもアクセス可能です。 便利といえば、便利ですが、プライベート用途のNASを公開設定で使うことは(当面)ないので、セキュリティ向上のためにも、いろいろと設定変更してみます。まずはいろいろと試したので、その様子を書いておきます。

デバイス検索の禁止

まずは、myqnapclod.com において、デバイスそのものの検索を禁止することができます。 QTSデスクトップの『myQNAPclod』→『アクセスコントロール』→『デバイスアクセス制御』で、プライベートを選択すると、myqnapcloud.com 画面から検索できなくなります。

f:id:junichim:20161004101401p:plain

ポート番号変更

デフォルト状態では、UPnpにより、以下のポートが(外部向けに)ルータに空いています。

  • 8080 : QTS Desktop, http
  • 8081 : Webサーバー, https
  • 8082 : QTS Desktop, https
  • 8083 : Webサーバー, http

ルータでUPnpの様子を表示させると、下記の様になっています。

f:id:junichim:20161004092739j:plain

それぞれが対応するポート番号もわかると思います。

このうち、内部ポート番号の8080番(QTS Desktop, http) は、QTSデスクトップから『コントロールパネル』→『システム設定』→『一般設定』→『システムポート』で変更することができます。 同様に、8081番のポート番号は、『コントロールパネル』→『アプリケーション』→『一般設定』→『Webサーバー』→『セキュア接続を有効にする』で変更することができます

これらはポート番号を変更すると、同時に対応する外部向けのポート番号も変更されます。 f:id:junichim:20161004093846p:plain (上図は、8081番を8084番に変更した場合の様子)

ですが、8082番、8083番のポート番号を変更する方法はわかりませんでした(443や80を変更すると、ローカル側のポート番号が変更されるため、単にUPnPで開けたポート番号からは接続できなくなります)。

プライベート化

もう少し試してみます。 デフォルト状態ですと、いくつかのサービスが公開状態になっています。 f:id:junichim:20161004095109p:plain

このうち、NAS Web (安全なNASウェブ)というのが QTS Desktop への接続になります。この『公開』状態は、myqnapcloudでストレージを見つけたら、誰でもアクセス可能になっている状態です。

f:id:junichim:20161004095759p:plain

ここで、『プライベート』にチェックを入れるとmyqnapcloud.comからアクセスしする際に、プライベートタブを開きますが、

f:id:junichim:20161004095742p:plain

のように、ユーザー名とアクセスコードの入力を求められます。なお、アクセスコードはプライベートにチェックを入れると、設定画面の下部に設定欄が表示されるので、そちらで入力可能となります。

公開停止

プライベートの機能は別の誰かにアクセスコード等を伝えて、共有するときに使います。でも、自分一人で使うなら、公開そのものが無くても問題ありません。 というときは、さきほどの設定画面で『公開』のチェックボックスを外して、公開そのものを取りやめてしまってもOKです。

注意点

さて、上記に書いたような方法で、外部からのアクセスを制御できるかと思いますが、これらはあくまでも myqnapcloud.com 経由でのアクセス設定を管理しているだけです。なので、アクセス用のURLを直接指定してブラウザでアクセスすれば、上記設定に関係なくアクセス可能です。ま、考えてみれば、NAS を自宅のLANの外部に公開するために、UPnP によりルータに穴をあけて、DDNSでURLを割り当てているので当然ですね。

外部ポート利用の停止

さて、いろいろと書いてきましたが、自宅のNASをインターネット上に公開してアクセスするのは、特段の理由もない場合は、怖いだけです。

ということで、最終的には、外部向けの公開を停止します。 QTSのデスクトップから『myQNAPcloud』→『自動ルータ構成』を選択し、『UPnPポート転送を有効化』のチェックを外します。

f:id:junichim:20161004100124p:plain

また、DDNSも不要になるので、『My DDNS』を選択し、『myQNAPclodd DDNSサービスを有効にする』のチェックも外しておきます。

あと、myqnapcloud.com でのデバイス検索をプライベートにし、公開サービスもなくしておきます。まあ、 myqnapclod.com を使わないのであれば、アカウントをサインアウトしてもよいのですが、ちょっと様子を見ようとも思いますので、このようにしました。

f:id:junichim:20161004104632p:plain

その他

もう一つついでに、QTS Desktop へのアクセスはhttpsに限定し、ポート番号も443から変更しておきます。 デフォルトでは、Web公開フォルダにある index.php が http://IPアドレス でアクセスすると、管理用インターフェースにリダイレクトする設定になっているので、このファイルを削除して、空の index.html ファイルを入れておきます。 あと、『コントロールパネル』→『セキュリティ』→『ネットワークアクセス保護』を表示して、『ネットワークアクセス保護を有効にする』にチェックを追加し、SSH/HTTPS/SAMBA にもチェックを入れておきます。

とりあえずこれで、自宅のLAN内部に侵入された場合も多少は防御できるかな?

次は機能的な面の設定をあれこれ触ってみたいと思います。

(参考)

chimtty.blogspot.jp

AndroidStudio のインストール (Windows環境)

いままで、Androidの開発は、Windows ホスト上の Ubuntu で eclipse+ADT でやってました(わざわざこんなことしてるのは、仕事単位で開発環境をいろいろと切り替えられるようにと、開発環境をいろいろといじって不安定になったときスナップショットで巻き戻してリカバーすることを可能にするためです)。

いい加減、AndroidStudio に移行したいなと思いつつも、お客さんとの絡みもあり、延び延びになってました。が、最近になってやっと AndroidStudio に移行できることになったので、やったと思い、Ubuntu上で環境を作ってみたら、これがなんと!話にならないぐらい遅くて、まあ、仕事で使い物になりません。

というわけで、当面は、ホストOS側のWindows上にAndroidStudioでの開発環境を作って対応することにしたので、環境構築についてメモにまとめておきます。 なお、(仮想マシンの)ubuntu上でのAndroidStudio開発構築についても、あきらめてはいないので、後日再トライしてみたいと思います。

インストール準備

AndroidStudio のインストールページ を見ても、あまり詳しく書いてありません。JDKも必要なのに、それすら(明確には)表記されてないです。

ということで、AndroidStudio のインストール準備として次のものをインストールしました。なお、OSは、Windows10 (64bit) です。

どちらもデフォルト設定でのインストールです。Java はインストール後、環境変数に JAVA_HOME を追加しておきます。

インストール

インストール準備ができたら、AndroidStudioのインストールです。これは特に問題もなく画面の指示に従ってインストールすれば終わります。

インストールが終わったら、プロジェクトの新規作成を行ってみます。これも画面の指示に従って選択していけば、問題なく完了し、AndroidStudioが立ち上がります。 仮想マシン上で試したときは、このときの初回ビルドがいつまでたっても終わらなかったのですが、今回の場合サクッと終わって、快適です。

VCSの有効化

Git を使うには、AndroidStudio を開いた状態で、メニューの『VCS』→『Enable Version Control Integration』 を選択します。バージョン管理システムの選択画面が表示されるので、gitを選択すると、gitリポジトリが、AndroidStudioプロジェクトのルートに作成されます(つまり、プロジェクト単位で作業を行う必要があります)。

この点は、eclipseと違いますね。eclipseの場合、プロジェクトのディレクトリと同じディレクトリにリポジトリを作るのは推奨されていませんでした。

ちなみに、当初は、AndroidStudio自体にgitのクライアント機能が含まれると思っていたのですが、gitインストール前だと、このメニューを選択してもエラーになります。おかしいな、と思ったら、ご自分の環境にgitがインストールされているか確認してください。

既存eclipseプロジェクトのインポート

既存eclipseプロジェクトのインポートもやってみます。移行手順も示されているので、その通りに作業するだけです。

  1. メニューの『File』→『New』→『Import Project』を選択します。
  2. インポート元のeclipseプロジェクトを指定します。この際、AndroidManifest.xmlが存在するディレクトリを指定してください。
  3. あとは、そのまま画面の指示に従えば、インポート処理が行われます。
  4. インポート後、いくつかエラーができることがあります。手元のプロジェクトの場合、下記のエラーなどがありました

    • gradle/wrapper.properties 内のバージョン番号の修正
  5. エラー修正後、ビルドに成功すれば、まあ、インポート成功です。

あとは、インポートした場合は、.gitignoreが存在していないので、適当な .gitignore を作成してgitにコミットすれば作業完了です。

(参考) インポートについてはこれなど詳しかったです

Android StudioにEclipseで作成したAndroidプロジェクトをインポートする - Narrow Escape

はてなブログに移行しました (2/2)

前の記事に引き続き、ここからは実際の移行作業について、メモを残したいと思います。

主な流れは、

Joomla! -> Wordpress -> はてなブログ

です。

以下、バージョン情報です。

  • Joomla! 3.6.2
  • Wordpress 4.5.3
  • FG Joomla to WordPress 3.15.3

Wordpress の立ち上げ

まず、Joomla!のコンテンツをWordpressに移行するため、Joomla!を運用しているのと同じサーバーでWordpressを立ち上げます。 森ソフトは、さくらインターネットで運用しているのですが、さくらインターネットのレンタルサーバーには、クイックインストールという機能があり、Wordpressはそちらで簡単にセットアップできるようです。

https://help.sakura.ad.jp/app/answers/detail/a_id/2319#ac02help.sakura.ad.jp

手順通りにすれば、問題なくWordpressが立ち上がりました。

Joomla! サイトのコンテンツをWordpressに移行

次は、Wordpressの管理画面に入り、『プラグイン』から『新規追加』を選択します。プラグインの検索で、『FG Joomla to Wordpress』を探すと、すぐに見つかります。

f:id:junichim:20160826101110p:plain

問題なくインストールができれば、プラグインを有効にします。 プラグインが有効になったら、『プラグイン』→『FG Joomla to WordPress』の『import』を選択して、インポートを開始します。

インポート作業は、画面に従ってオプションを指定するだけです。 Joomla!のサイトおよびデータベースへの接続情報を正しく入力しておきます。『Test the database connection』を実行して正しく接続できることを確認しておいてください。

その他のオプションとしては、

  • Automatic removal : チェックを入れる(インポート前のコンテンツをすべて削除するため)
  • Import introtext : to the content を選択
  • Archived post : not imported を選択
  • Medias : Force media import. Keep unchecked except if you had previously some media download issues. : チェックを入れる

としました(他はデフォルトだったはずです)。

これで準備ができましたので、『Start/Resume the import』ボタンを押すとインポートが始まります。 問題なくインポートが完了したら、画面の一番下にある『Modify internal links』ボタンを実行して、内部リンクを更新しておきます。

画像もインポートしてくれるんで、非常にありがたいです。

なお、このプラグインを利用した際に、若干注意するべき点がありました。こちらにまとめてありますので、気になる方はお読みください。

Wordpress のコンテンツをはてなブログにインポート

さて、無事にJoomla!のコンテンツをWordpressにインポートできれば、次は、Wordpressのコンテンツをエクスポートします。 管理画面から『ツール』→『エクスポート』とすすみ、『すべてのコンテンツ』を選択して、『エクスポートファイルをダウンロード』とすると、コンテンツの内容がファイルにエクスポートされます。あ、エクスポート前に、不要な記事やカテゴリ・タグなどがあれば、消しておきます。

次に、エクスポートしたファイルを、はてなブログ側の『インポート』で指定すれば、記事のインポートは完了です!インポートの形式として、WordPress形式を指定してください。 はてなの場合、記事にインポートに続き、画像のインポートをしてくれます。これは、インポート元のサイトから画像のURLを使って、記事内の画像をすべてコピーして、はてなフォトライフに保存してくれるというものです。これは素晴らしいですね!

なお、この際、下記の点に気を付けてください。

  • 元サイトにアクセスできないと画像のインポートができません
  • 一度インポート後、インポートをやり直したい時があると思います。そのとき、『インポートの削除』を実行すると、記事は削除されますが、画像は削除されません。なので、引き続き同じサイトからインポートすると同じ画像が保存されることになります。

後者のような場合は、再インポート前に、一旦、はてなフォトライフに移り、インポートした画像を手作業で削除したほうが良いかもしれません。なお、はてなフォトライフ側には、『使用中の画像をチェックする』とか『未使用の画像をチェックする』のような機能はないので、あとから作業しようとすると結構大変そうな予感がしました。

これで、基本的にはインポートができるのですが、残念ながら、これですべて完了とはなりません。 いくつかの点については、手作業で対応する必要があります。今回の移行作業で行った部分を以下に書いておきます。

SyntaxHighLighterの導入

元々、コードの表示には、SyntaxHighlighterを利用した、Joomla!のプラグインを使っていました。はてなブログのシンタックスハイライト機能を使ってもよかったのですが、既存の記事に対する修正が不要になるので、Syntax Highlighter を使うことにしました。

Syntax Highlighter の使い方は、ネットを調べるといくつか出てきます。

はてなblogでsyntaxhighlighter.autoloaderをつかってC#ソースコードをきれいに表示させる方法 - kaz16a's blog

SyntaxHighlighterのautoloaderの使い方 Ver 3.0 | Asterlist

はてなブログの場合、『デザイン』を開き、『カスタマイズ』(スパナの画像)タブを選択し、『サイドバー』を選択します。 『モジュールを追加』をクリックし、『HTML』を選択します。その内部に、Syntax Highlighter を使うための設定を記述します。 今回は下記の様な、Autoloaderを使う設定にしています。

<!-- Syntax HighLighter -->
<link href="https://xxx.example.com/syntaxhighlighter/styles/shCore.css" rel="stylesheet" type="text/css" />
<link href="https://xxx.example.com/syntaxhighlighter/styles/shThemeDefault.css" rel="stylesheet" type="text/css" />
<script src="https://xxx.example.com/syntaxhighlighter/scripts/shCore.js" type="text/javascript"></script>
<script src="https://xxx.example.com/syntaxhighlighter/scripts/shAutoloader.js" type="text/javascript"></script>
<script type="text/javascript">
function path()
    {
        var args = arguments,
            result = []
            ;
             
        for(var i = 0; i < args.length; i++)
            result.push(args[i].replace('@', 'http://xxx.example.com/syntaxhighlighter/scripts/'));
             
        return result
      };
       
      SyntaxHighlighter.autoloader.apply(null, path(
        'applescript            @shBrushAppleScript.js',
        'actionscript3 as3      @shBrushAS3.js',
        'bash shell             @shBrushBash.js',
        'coldfusion cf          @shBrushColdFusion.js',
        'cpp c                  @shBrushCpp.js',
        'c# c-sharp csharp      @shBrushCSharp.js',
        'css                    @shBrushCss.js',
        'delphi pascal pas      @shBrushDelphi.js',
        'diff patch             @shBrushDiff.js',
        'erl erlang             @shBrushErlang.js',
        'groovy                 @shBrushGroovy.js',
        'java                   @shBrushJava.js',
        'jfx javafx             @shBrushJavaFX.js',
        'js jscript javascript  @shBrushJScript.js',
        'perl pl                @shBrushPerl.js',
        'php                    @shBrushPhp.js',
        'text plain             @shBrushPlain.js',
        'ps powershell          @shBrushPowerShell.js',
        'py python              @shBrushPython.js',
        'ruby rails ror rb      @shBrushRuby.js',
        'sass scss              @shBrushSass.js',
        'scala                  @shBrushScala.js',
        'sql                    @shBrushSql.js',
        'vb vbnet               @shBrushVb.js',
        'xml xhtml xslt html    @shBrushXml.js'
      ));
      SyntaxHighlighter.all();
</script>

なお、jsファイルやcssは自分が利用可能な適当なサーバーに配置するのがおすすめです。ちなみに、

http://alexgorbatchev.com/SyntaxHighlighter/hosting.html

を見ると、公式にホストされたものもありますが、きっと負荷も高いでしょうからあくまでもご参考までに。 これで、コードのハイライト表示は完了です。

画像以外のファイル置き場

はてなブログですが、画像は、はてなフォトライフに保存されますが、それ以外のソースコードのファイルやその他各種のファイルは、アップロードすることができません。

調べてみると、はてなブログのproであれば、はてなダイアリープラスが利用でき、そちらに任意のファイルをアップロードする機能があるので、それを使うことも可能です。

はてなブログでファイルをアップロードする方法 - ブログ鯖人

ですが、ちょっと試してみましたが、なんとなくいまいち。要は、はてなダイアリーはアップロード先としてだけ使いたくて、公開する必要もないのですが、公開設定にしないとリンク先が正しく表示されません。 まあ、元々の目的が違うんでしょうね、きっと。

ということで、dropboxに公開用のファイルを保存しておき、共有リンクでダウンロード可能としました。 なお、dropboxに置いたファイルをscript等で使う場合(.jsファイルを読み込むとか)は、リンクURLのパラメータでdl=1を与えるように変更します。

共有された Dropbox リンクのダウンロードを強制する | Dropbox ヘルプ

このようにしないとダウンロードが始まらないため、scriptファイル等を読み込めなくなります。

内部リンクの修正

さて、実はこれが一番手間がかかりました。 はてなブログでは、Wordpressのコンテンツのインポートはしてくれるのですが、同一サイト内の記事間の内部リンクの修正はやってくれません。そのため、ある記事内で別の記事を参照していたりすると、すべてインポート元(この場合は、Wordpressのサイト)を指してしまいます。

まあ、昔の記事で修正する意味がどれだけあるかは難しいところですが、一応過去の資産と考えて、修正しました。

一応、リンク切れについては、

リンクチェッカー(リンク切れチェックツール) dead-link-checker.com

などを使ってチェックできるので、これでエラーになった箇所で、かつインポート元を指しているものについて、一つずつ確認して、手作業での手直しになりました。

※本当は、一旦、はてなブログにインポートして、記事のURLがどう変化するかを把握して、Wordpressからエクスポートしたxmlファイルをスクリプトで処理するほうがいいんだと思いますが、今回は力技に逃げました。

URLの自動リンクを停止

はてなブログでは、URLが書かれていると、自動でリンクを張ってくれます。 通常は非常に便利なのですが、これが邪魔になるときもあります。

通常のURLの場合

通常の場合の自動リンクの抑制方法は、下記にあるように、URLの前後を [] で囲めばよいようです。

はてなブログ ヘルプ

https://hapilaki.hateblo.jp/entry/no-auto-linkhapilaki.hateblo.jp

preタグ内の場合

Syntax Highlighterを使っていると、preタグ内にURLを記述する、という場面が多く出てくると思います。 何もしなければ、このpreタグ内のURLに対しても、リンクが張られてしまいます。ま、それが正しく表示されれば別にいいのですが、preタグ内のためか、<a href="・・・ なんて、文字列が見えるので、いただけません。 また、preタグ内のため、前述の [] を使った方法も正しく動作しません。

この場合の回避方法も、すでに確立されているようで、

はてなブログでSyntaxHighlighterを利用する時は「data-unlink」をお忘れなく - altere5's blog

にあるように、data-unlink 属性を追記すれば、避けることができるそうです。

mimeTex を復活

はてなブログでは、LaTeX 記法による数式表示が使えるようです。 森ソフトのサイトでは、Joomla!のアップデートに伴い、mimeTexのプラグインが使えなくなっていたので、はてなブログ用の記法を使って書き直しました。 とはいっても、記事1つだけなんですけどね。

終わりに

ここまでやれば、移行作業はほぼ終わりです。たぶん、新しいブログを運用していくと、改善しないといけない点も出てくるでしょうが、とりあえずOKとします。 しばらく様子をみて、問題なさそうなら、元サイトの記事のクローズとリダイレクト設定を行いたいと思います。

(参考)FG Joomla to Wordpress 使用上の注意点について

改行文字

普通にインポートすると、preタグ内のコードが1文につながってしまうという問題がありました。 Joomla! 側のデータベースで、記事本文を格納しているのが、 (prefix)_content テーブルの introtext カラムでしたので、これらの手掛かりに、該当部分を探すと、

        public function process_content($content, $post_media) {

            if ( !empty($content) ) {
                $content = str_replace(array("\r", "\n"), array('', ' '), $content);
                                                                                                                                                              
                // Replace page breaks
                $content = preg_replace("#<hr([^>]*?)class=\"system-pagebreak\"(.*?)/>#", "<!--nextpage-->", $content);
                                                                                                                                                              
                // Replace media URLs with the new URLs
                $content = $this->process_content_media_links($content, $post_media);

                // Replace audio and video links
                $content = $this->process_audio_video_links($content);
                                                                                                                                                              
                // For importing backslashes
                $content = addslashes($content);
            }                                                                                                                                                 
                                                                                                                                                              
            return $content;
        }

となっており、改行コードを空白で置き換えていることがわかります。

今回の場合、Wordpressのコンテンツとして扱う分に、何か支障があるかもしれませんが、最終的にはてなブログで思ったように取り込めればよいと考え、かなり乱暴ですが、この部分の処理をコメントアウトしてからインポート処理を行うことで、preタグ内のコードがすべてつながってしまうという事態を避けることができました。

画像ファイルコピー失敗時の原因調査について

最初、FG Joomla to WordPress を使ってインポートしようとしたら、記事のインポートは問題なかったのですが、画像のインポートにことごとく失敗していました。 こんな感じのエラーメッセージが出ていました。

f:id:junichim:20160826224705p:plain

結局のところ原因は、作業をしていたサイトが、特定のIPアドレスからの接続のみを受け付ける設定となっており、自分自身のIPでの接続を許可していなかったためでした。

この原因の探り方を参考に書いておきます。 まず、

https://wordpress.org/support/topic/plugin-fg-joomla-to-wordpress-media-does-not-copy

にあるように、copy関数呼び出しでエラーメッセージが抑制されていそうなので、これを知りたいと思い、該当部分を探すと、今回使ったバージョンだと、

wp-content/plugins/fg-joomla-to-wordpress/admin/class-fg-joomla-to-wordpress-admin.php

の1813行に、

if ( ! @$this->remote_copy($old_filename, $new_full_filename) ) {
    $error = error_get_last();
    $error_message = $error['message'];
    $this->display_admin_error("Can't copy $old_filename to $new_full_filename : $error_message");
    return false;
}                                                                                                                                                 

という記述があり、コピー時のエラーメッセージが抑制されていました。 これを、

if ( ! $this->remote_copy($old_filename, $new_full_filename) ) {

のようにエラー解除すると、エラーメッセージとエラーの発生行を知ることができます。

今回の場合は、エラー発生時に表示された該当行付近を見ると、

            $response = wp_remote_get($url, array(
                'timeout'     => $this->plugin_options['timeout'],
            )); // Uses WordPress HTTP API
                                                                                                                                                              
            if ( is_wp_error($response) ) {                                                                                                                   
                trigger_error($response->get_error_message(), E_USER_WARNING);
                return false;
            } elseif ( $response['response']['code'] != 200 ) {
                trigger_error($response['response']['message'], E_USER_WARNING);
                return false;
            } else {                                                                                                                                          
                file_put_contents($path, wp_remote_retrieve_body($response));
                return true;
            }

となっており、レスポンスステータスが200以外(若干のデバッグ文も加えたところ、403でした)となっているが判明し、そこから、IPアドレスを制限していることを思い出しました。

ご参考までに。