【macOS】ルーターの注意喚起が出たら arp-scan がいいよ

ああ、ルーターの機種がもろ該当。

 

🛜 Buffalo バッファロー のルーターで注意喚起が出た

こういうの良く出てますけども。

対象の製品を利用していること、そしてWeb設定画面のパスワードが工場出荷時のまま、もしくは推測しやすい文字列を設定していることの両方を満たす場合には、bot感染の可能性がある。

👉 バッファローが一部Wi-Fiルーターで注意喚起、bot感染増加を受け パスワード変更やファームウェア更新を - ITmedia NEWS hatena-bookmark

1つは、一旦設定を初期化すること。「インターネット設定等を工場出荷時のまま利用されている場合は、可能な限り設定を初期化しご利用ください」との表現がされているが、工場出荷時の状態から利用し続けている場合、意図しない設定変更が行われているおそれがあるので、一度初期化したのち、以下の対策を行ってほしい、との意図だという。

 次に、パスワード(ここで指しているのは、Wi-Fi接続用のパスワードではなく、Web設定画面にログインするための管理パスワード)を推測されにくい複雑なものに変更するとともに、ファームウェアを更新すること。なお、WSR-600DHPは工場出荷時の状態でファームウェアが自動更新されるようになっているが、ほかの4製品は自動更新機能を持たないため、手動での更新が必要となる。

 最後に、Web設定画面の[詳細設定]-[管理]-[システム設定]にて、「Internet側リモートアクセス設定を許可する」が無効になっていることを確認すること。なお、設定の初期化を行った場合は、この設定は無効になるため、確認の必要はないという。

👉 【追記あり】バッファローのWi-Fiルーター「WSR-1166DHP」シリーズほかのボット感染が増加、NICTER解析チームが警告 - INTERNET Watch hatena-bookmark

脆弱性の話はいつもあいまいなはっきりしない対応策が多いので分かりづらい。

注意はすればするほど安全なのだろう。

バッファロー公式のアナウンスを見る。

👉 NICTERの投稿に関する重要なお知らせ(5/23更新) | バッファロー hatena-bookmark

調査中の雰囲気ですが、

「外部から管理画面にアクセスしてパスワードを突破されて何かを仕込まれる。」

ということですよね。

対処法としては、

- 外部からのアクセス機能をOFFにする。
- パスワードをややこしいものにする。
- ファームウェアを最新のものにする。

ということのようです。

「初期化」という言葉が話をややこしくしていますが、

どちらにしても、ルーターの設定を触る必要がありますね。

 

🛜 ルーターの管理画面

パソコンやスマホに公式設定アプリを入れて操作するのが簡単ですのでおすすめです。

👉 ソフトウェア | バッファロー hatena-bookmark

しかし、いちいちアプリを入れたくないですよね !

今どきの個人向けルーターは、

ほぼブラウザでアクセスできる管理画面を持っています。

そして、それぞれのOS上で動く設定アプリ内でも

そのネットワーク上に存在しているルーターの

ホスト名やIPアドレスを検出しているはずです。

ブラウザからIPアドレス直打ちで管理画面開きたいですよね!

 

🛜 IPアドレスを見つける

「arp-scan」を使います。


❯ brew install arp-scan


👉 royhills/arp-scan: The ARP Scanner hatena-bookmark

root 必要です。


❯ sudo arp-scan -l
Interface: en0, type: EN10MB, MAC: 63:7e:67:a2:cd:1f, IPv4: 192.168.151.16
Starting arp-scan 1.10.0 with 512 hosts (https://github.com/royhills/arp-scan)
192.168.151.11	84:a3:ec:9c:16:08	BUFFALO.INC
192.168.151.14	f8:3f:c2:31:d2:ee	Apple, Inc.

「BUFFALO」ありましたので、

まずは、コンソールからアクセスします。


❯ curl 192.168.151.11
<html>
<head>

<title>Redirect Page</title>
<meta http-equiv="expires" content="-1">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<SCRIPT language=JavaScript>
function init()
{
	top.location.replace("../login.html");
}
</SCRIPT>
</head>
<body onload='init();'>
<table><tr><td></td></tr></table>
</body>
</html>

❯ curl 192.168.151.11:443
curl: (7) Failed to connect to 192.168.151.11 port 443 after 16 ms: Couldn't connect to server

❯ curl 192.168.151.11:80
<html>
<head>

<title>Redirect Page</title>
<meta http-equiv="expires" content="-1">
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
<SCRIPT language=JavaScript>
function init()
{
	top.location.replace("../login.html");
}
</SCRIPT>
</head>
<body onload='init();'>
<table><tr><td></td></tr></table>
</body>
</html>

80 のみなので http のみです。

ブラウザから見ると login.html にリダイレクトされます。

あとは、ログインして公式アナウンスの推奨する対応策をやれば OK。

 

🛜 参考



【SwiftUI】Default background Color in built-in View Component

上は GroupBox を使って、

下は それに似せて Stack系のViewで書く。


GroupBox("Today's Menu 1") {
  VStack(alignment: .leading) {
    Text("🍛 curry and rice")
    Text("🥗 green salad")
  }
}
.frame(width: 300)

VStack {
  HStack {
    Text("Today's Menu 2")
      .bold()
    Spacer()
  }
  VStack(alignment: .leading) {
    Text("🍛 curry and rice")
    Text("🥗 green salad")
  }
}
.padding()
.frame(width: 300)
.background(
  .background, // *
  in: .rect(cornerRadius: 8)
)

背景色が違う !

 

🧑🏻‍💻 意図しない背景色

特に背景色を意識せずに画面を構成していくと、

微妙に色が違うことありません ?

そもそもデフォルトの背景色はどんな色なのですか。

もちろん、Color クラスに定義されてますよね?

簡単に呼び出せますよね ?

Light / Dark の変化に対応してますよね ?

 

🧑🏻‍💻 地道に調べる

Xcode のカラーピッカーで調べます。


Edit

 ↓

Format

 ↓

Show Colors

RGB で opacity 100% で


//       light               dark  
// 0.949 0.949 0.969 | 0.110 0.110 0.118

でした。

 

🧑🏻‍💻 既存の背景色 (Light/Dark 対応)

これ、SwiftUI.Color で定義されてませんよね。

UIColor の定義でそれらしきのものを見つけて、

数値を取ってみます。


//                           opacity 100%          light               dark
Color(.systemBackground)                  // 1.000 1.000 1.000 | 0.000 0.000 0.000
Color(.secondarySystemBackground)         // 0.949 0.949 0.969 | 0.110 0.110 0.118
Color(.tertiarySystemBackground)          // 1.000 1.000 1.000 | 0.173 0.173 0.180
Color(.systemGroupedBackground)           // 0.949 0.949 0.969 | 0.000 0.000 0.000
Color(.secondarySystemGroupedBackground)  // 1.000 1.000 1.000 | 0.110 0.110 0.118
Color(.tertiarySystemGroupedBackground)   // 0.949 0.949 0.969 | 0.173 0.173 0.180

どうやら、GroubBox デフォルト背景色は、


Color(.secondarySystemBackground)

と同じもののようです。

GroupBoxStyle に定義されているのでしょうが、

見つけられませんでした。

 

🧑🏻‍💻 まとめ

こういうの困りません?

なんだか単に「色」といってもかなり深そう。

👉 大解剖!UIColorファミリー by しもとり | トーク | iOSDC Japan 2020 - fortee.jp hatena-bookmark

iOS まわりの激しい変化の歴史を感じます。

👉 【SwiftUI】CardView のような GroupBox は本当に便利なのか hatena-bookmark


【SwiftUI】市松模様を背景にする - Checkered Pattern Background 🏁

既存 View の 背景色。

分からないときありません ?

白なのか、グレーなのか、

透過しているのか、マテリアル的なやつなのか。

 

🏁 市松模様 Checkered Pattern

作っておきます。


struct CheckeredPattern: View {
  var size: CGFloat

  var body: some View {
    GeometryReader { gr in
      Grid(horizontalSpacing: 0, verticalSpacing: 0) {
        ForEach(0 ..< Int(ceil(gr.size.height / size)), id: \.self) { y in
          GridRow {
            ForEach(0 ..< Int(ceil(gr.size.width / size)), id: \.self) { x in
              (x % 2 == y % 2 ? Color.gray : Color.white)
                .frame(width: size, height: size)
                .opacity(0.25)
            }
          }
        }
      }
    }
  }
}

🏁 市松模様 - Checkered Pattern

 

🏁 Preview で使う


struct BackgroundCheckeredPattern<Content: View>: View {
  var size: CGFloat
  @ViewBuilder var content: () -> Content

  var body: some View {
    ZStack {
      CheckeredPattern(size: size)
        .edgesIgnoringSafeArea(.all)
      content()
    }
  }
}

 

🏁 extension 化

Preview などで使いやすように extension にしておきます。


extension View {
  func backgroundCheckeredPattern(size: CGFloat) -> some View {
    ZStack {
      CheckeredPattern(size: size)
        .edgesIgnoringSafeArea(.all)
      self
    }
  }
}

特に modifier まで作ることはないですね。


Button("Button") {
}
.buttonStyle(.bordered)
.controlSize(.extraLarge)
.backgroundCheckeredPattern(size: 15) // *

🏁 市松模様 - Checkered Patter

 

🏁 まとめ

サンプルコードとして Gist 化しておきます。



List の背景って .scrollContentBackground(.hidden) で消すんですね。

List の背景って .scrollContentBackground(.hidden) で消す

便利に使えるコードはたくさん持っておきたいです。


【SwiftUI】TextField で debounce | Debouncing TextField

みんなは、どんな実装にしていますか。

入力文字を監視しつつの検索結果のリアルタイム反映的なやつを作るとき。

詰まる感じをどう解消していますか。

Debounce
only emit an item from an Observable if a particular timespan has passed without it emitting another item

👉 ReactiveX - Debounce operator hatena-bookmark

👉 debounce(for:scheduler:options:) | Apple Developer Documentation hatena-bookmark


import Combine

public final class DebounceObject: ObservableObject {
  @Published var text: String = ""
  @Published var debouncedText: String = ""
  private var bag = Set<AnyCancellable>()

  public init(dueTime: TimeInterval = 0.5) {
    $text
      .removeDuplicates()
      .debounce(for: .seconds(dueTime), scheduler: DispatchQueue.main)
      .sink(receiveValue: { [weak self] value in
        self?.debouncedText = value
      })
      .store(in: &bag)
  }
}


struct SearchView: View {
  @StateObject var debounceObject = DebounceObject()

  var body: some View {
    VStack {
      TextField(text: $debounceObject.text)
        .onChange(of: debounceObject.debouncedText) { text in
          // perform search
        }
    }
  }
}

👉 How to debounce TextField search in SwiftUI | Swift Discovery hatena-bookmark

combine てのもう時代遅れなのですか ?

今現在、本流の本筋の考え方のわかりやすいシンプルな記述を探します。

 

🤔 Tunous/DebouncedOnChange

直感的に使いやすい ViewModifier ライブラリです。

👉 Tunous/DebouncedOnChange: SwiftUI onChange View extension with debounce time hatena-bookmark

コード量が少ないので内部も把握しやすいです。

基本的な使い方は、0.25 秒をデバウンス時間として以下のように書けます。


TextField("Search-1", text: $text)
  .onChange(of: text, debounceTime: .seconds(0.25)) { newValue in
    debouncedText = newValue
  }

使ってみると分かるのは、View 内に @State として、

textdebouncedText

の2つが存在してしまうことが面倒です。

なので、それを避けるために、

DebounceTextField として View を外出しにして使います。


DebounceTextField2(titleKey: "Search-2", debouncedText: $debouncedText)


struct DebounceTextField2: View {
  var titleKey: String
  @Binding var debouncedText: String

  @State private var local = ""

  var body: some View {
    TextField(titleKey, text: $local)
      .onChange(of: local, debounceTime: .seconds(0.25)) { newValue in
        debouncedText = newValue
      }
  }
}

onChange() を使うのはどうなのか。

 

🤔 Binding をカスタムする

そもそも @State は、

@Binding な引数をもつコンポーネントに対して双方向に値が流れる

ということをきちんと頭に置きながら考えてみます。



struct DebounceTextField3: View {
  var titleKey: String
  @Binding var debouncedText: String

  @State private var delay: Task<Void, Never>?

  var body: some View {
    TextField(
      titleKey,
      text: Binding(
        get: { debouncedText },
        set: { newvalue in
          delay?.cancel()
          delay = Task {
            do {
              try await Task.sleep(for: .seconds(0.25))
            } catch { return }
            debouncedText = newvalue
          }
        }
      )
    )
  }
}

続いて、ちょっとしっかりしたライブラリを使ってみます。

👉 boraseoksoon/Throttler: One Line to throttle, debounce and delay: Say Goodbye to Reactive Programming such as RxSwift and Combine. hatena-bookmark


struct DebounceTextField4: View {
  var titleKey: String
  @Binding var debouncedText: String

  var body: some View {
    TextField(
      titleKey,
      text: Binding(
        get: { debouncedText },
        set: { newvalue in
          debounce(.seconds(0.25)) {
            debouncedText = newvalue
          }
        }
      )
    )
  }
}

 

🤔 まとめ

Custom Binding を使ったほうがスッキリします。



【Xcode】Indexing | Processing files could not complete

これ。

Preview やDerivered data を削除しても、

Build folder をクリーンしても、

Xcode を再起動しても

Index Procccessing Files のまま固まって

Preview のビルドができなくなった場合の対応手順。

1. Open your Project Folder.
2. Find ProjectName.xcodeproj file.
3. Right-Click Copy and Paste to Safe Place.
4. Right-Click Show Package Contents.
5. Find project.xcworkspace file and delete that file.
5. Reopen Your Project and clean and Rebuild.

👉 Xcode stuck on Indexing - Stack Overflow hatena-bookmark

覚えておくのは、

「プロジェクト名」.xcodeproj ファイルを

右クリックから開いて、

project.xcworkspace を捨てる。

とりあえず、これで復旧できます。

スタックの原因自体は、

特定のコードのバグのようなので、

おおまかに位置を特定したら、

最初にコメントアウトしておかないと、

また固まっちゃうので注意です。